3

Salutations,Est-ce que Scala peut être vu comme une 'Inversion d'Abstraction'?

C'est une question provocante, visant à ouvrir le débat sur la façon dont l'inversion d'abstraction sont perçues dans la communauté des développeurs. Je suis vraiment curieux de savoir ce que tu penses.

Tout d'abord, voici une citation des exemples d'inversion d'abstraction donnée par Wikipedia: http://en.wikipedia.org/wiki/Abstraction_inversion

Création d'un objet pour représenter une fonction est lourde dans les langages orientés objet tels que Java et C++, dans lequel les fonctions ne sont pas des objets de première classe. En C++, il est possible de rendre un objet 'callable' en surchargeant l'opérateur(), mais il est encore souvent nécessaire d'implémenter une nouvelle classe, comme les Functors dans la STL.

Pour moi fonctions sont des citoyens de première classe à Scala, mais quand nous utilisons Scala pour générer bytecode Java, Scala Créer une classe spécifique « sur » de Java pour rendre la programmation fonctionnelle possible ... peut-on voir ce comme une inversion d'abstraction?

même peut demander à Clojure ou toute autre langue pour la machine virtuelle Java fonctionnelle ... ou même Collections Apache, pour cette exemple:

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/Closure.html


BTW, je ne suis pas convaincu de la wikipedia article objectivité. Par exemple quand on parle de l'inversion possible d'abstraction dans micronoyau l'article dit « Un corps d'opinion tient la conception de micronoyau être une inversion d'abstraction » mais pas une telle déclaration pour le type fonctionnel dans POO

Répondre

9

L'article wiki est vraiment faible (représente-t-il une inversion d'abstraction elle-même?), Et le concept même est un peu douteux. Mais l'essentiel est que quelque chose de fondamental est caché par l'abstraction, forçant les utilisateurs de cette abstraction à le ré-implémenter. Par exemple, à partir de la page de discussion, vient un exemple beaucoup plus intéressant. Supposons qu'un processeur ait une fonction mathématique tan, mais pas sin ou cos, et un langage de programmation implémenté sin et cos en termes de tan, mais n'expose pas tan lui-même. Un programmeur utilisant ce langage serait forcé de mettre en œuvre tan en termes de sin et cos, qui, eux-mêmes, sont implémentés en termes de tan, caractérisant ainsi l'inversion d'abstraction.

Alors revenons à Scala. Naturellement, un programmeur utilisant des fonctions dans Scala ne subit pas d'inversion d'abstraction, car il n'est pas obligé de ré-implémenter une fonctionnalité disponible en tant que primitive à Scala. D'autre part, on peut affirmer que l'implémentation de Scala des fonctions en tant qu'instances de classe est une instance d'inversion d'abstraction. Pour que cela soit vrai, cependant, deux choses doivent également rester vraies:

  1. Une primitive de "fonction" doit être disponible pour JVM.
  2. Une telle primitive doit avoir offert une alternative à ce que fait Scala.

Qu'est-ce qu'une fonction? A quoi ressemblerait une primitive de fonction? Dans ce contexte, "fonction" signifie des données qui peuvent être exécutées. On pourrait dire que tout code d'assembleur est, en fait, des données qui peuvent être exécutées - seulement elles ne sont pas portables, et, de plus, ne sont pas codées par un code, échouant ainsi aux principes de conception. D'autre part, toutes les méthodes en Java sont référencées par un identifiant, à travers lequel Java localise le code à exécuter pour la hiérarchie de classe d'un objet donné. Cet identificateur n'est pas exposé, bien qu'il puisse être utilisé indirectement par réflexion. Si elle était exposée, et que certaines fonctionnalités proposaient de dire «appelez ce code», alors une fonction pourrait sans doute être construite autour de cela. Donc, je pense qu'un cas pourrait être fait pour que 1 soit vrai. Passons à la suivante.

Si Java offrait un type de données "méthode", les fonctions Scala cesseraient-elles d'être des instances d'une classe? Non, ils ne le feraient pas. L'un des aspects fondamentaux de Scala est que chaque élément d'un programme en cours d'exécution est un objet. Les "primitives" que Java a déjà sont présentées comme si elles étaient des objets normaux avec des méthodes, et s'il y avait une primitive "méthode", il en irait de même.

Une conséquence possible des primitives de méthode serait d'élever les méthodes à des citoyens de première classe, mais les fonctions, elles-mêmes, ne changeraient guère.

+1

votre un !! + 1000 pour comprendre en profondeur la question, donner une très bonne réponse détaillée et .. être un communicateur FreeBSD! Merci beaucoup, et je suis d'accord que cet article est pure merde ... doit être réécrit ou supprimé. –

2

Non, il peut » t être vu comme une inversion d'abstraction. La raison est simple: Dans Scala vous avez un choix quel niveau d'abstraction vous préférez. La plupart du temps, il est plus commode d'écrire

val f = 2 * (_:Int) 
//--> f: (Int) => Int = 

f(21) 
//--> res5: Int = 42 

mais il n'y a aucun problème de le faire le chemin « long »:

val f = new Function1[Int,Int] { def apply(v:Int) = 2*v } 
//--> f: java.lang.Object with (Int) => Int = 

f(21) 
//--> res6: Int = 42 

Comme fonction personnaliséeN sont des traits, il est possible d'utiliser l'héritage mix-in , ce qui vous permet d'éviter des situations comme celle de Functors en C++. Par exemple. vous pouvez « moderniser » Java-Map en fonction:

class JavaMap[K,V] extends java.util.HashMap[K,V] with Function1[K,V] { 
    def apply(k:K) = get(k) 
} 

val m = new JavaMap[Int, String] 
m.put(5,"five") 
m(5) 
//--> res8: String = five 
5

La mise en œuvre d'une fonction par un objet ne se fait pas simplement parce que ce ce qui est possible sur la machine virtuelle Java, il va droit à la philosophie sous-jacente de la Scala.

tout est un objet: fonctions, acteurs, littéraux, etc. Il est également possible pour tout objet d'être appliable (en définissant la méthode apply()) sans être en fait une sous-classe de fonction personnaliséeN.

Cette dualité est fondamentale dans la conception de nombreuses API de bibliothèque standard, elle permet, par ex. Les cartes doivent être considérées à la fois comme une fonction (mappage des clés sur les valeurs) et comme un objet (une collection de paires clé/valeur). Scala est un véritable hybride objet/fonctionnel, aucun de ces deux paradigmes n'étant dominant.

+2

+1 pour l'approche philosophique :-) – Landei

+1

Je le fais seulement pour les upvotes :) –

1

Je ne crois pas. La façon dont les fonctions de première classe sont implémentées dans Scala est juste un détail d'implémentation.