Pourquoi de nombreux langages de programmation dynamique de type canard utiliseraient-ils une approche basée sur les classes au lieu de la POO basée sur des prototypes?

23

Étant donné que de nombreux langages de programmation dynamiques ont la caractéristique de taper du canard , et ils peuvent également ouvrir et modifier des méthodes de classe ou d'instance à tout moment (comme Ruby et Python ), alors…

Question 1) Quel est le besoin d'une classe dans une langue dynamique? Pourquoi le langage est-il conçu de cette façon pour utiliser une classe comme une sorte de «modèle» au lieu de le faire de la manière prototype et d'utiliser simplement un objet?

JavaScript est également basé sur des prototypes, mais CoffeeScript (la version améliorée de JavaScript) choisit la méthode basée sur les classes. Et il en va de même pour Lua (basé sur des prototypes) et MoonScript (basé sur des classes). De plus, il y a de la classe dans ES 6. Donc…

Question 2) Cela suggère-t-il que si vous essayez d'améliorer un langage basé sur des prototypes, entre autres, vous devriez le changer en classe? Sinon, pourquoi est-il conçu de cette façon?

iceX
la source
9
De nombreux programmeurs ne veulent pas se soucier d'apprendre quelque chose de nouveau. (C'est trop étranger et "difficile"). D'où toutes ces bibliothèques et langages basés sur les classes qui les compilent.
Thomas Eding
1
Je suis d'accord avec Thomas, mais ce qui est drôle, c'est qu'après avoir appris l'approche dynamique, c'est en fait plus facile (pas plus difficile). Le concept des objets est toujours là, c'est juste que les objets peuvent être modifiés sans recompiler d'abord un "plan" stupide. Si je veux mettre une 5e jambe sur une chaise, je ne veux pas avoir à modifier un plan d'abord, je veux juste ajouter la jambe. Les langages dynamiques modélisent plus étroitement la réalité à mon avis.
Lonnie Best
1
La POO a été inventée dans un contexte typé typiquement, où les types doivent être déclarés. Là, les classes sont une avancée sensible par rapport aux enregistrements et aux modules. La POO basée sur un prototype n'a jamais été qu'un sujet de recherche intéressant pour le langage Self, et en a en quelque sorte fait de JavaScript le moyen le plus simple de cocher le mot à la mode «POO» pour un langage essentiellement fonctionnel. La bonne chose est que vous pouvez implémenter des classes au-dessus des prototypes. Bien que j'aime les métaobjets, la séparation des classes de leurs instances facilite l'écriture de code bien factorisé, simple et faiblement couplé.
amon
3
Première chose: JavaScript lui-même prend en charge le classmot - clé à partir de la prochaine norme ECMAScript (ECMAScript 6). La prise en charge des classes en JavaScript est prévue depuis longtemps. Maintenant pour ce que c'est - les classes ne sont que du sucre syntaxique, un raisonnement plus facile sur le modèle pour les objets du même type. C'est comme ça en JS et c'est comme ça en Python et dans d'autres langages dynamiques.
Benjamin Gruenbaum
1
@BenjaminGruenbaum "... les classes ne sont que du sucre syntaxique ..." wow, c'est un peu une idée assez nouvelle pour moi, vraiment, pour des langages comme le rubis et le python, il semble que peu importe si vous utilisez un objet ou classe comme modèle - les deux peuvent être modifiés à la volée de toute façon. Et peu importe comment ils gèrent l'héritage non plus. Donc, peut-être qu'il n'est pas nécessaire de faire la distinction entre l'approche basée sur les classes et l'approche basée sur les prototypes pour un langage dynamique :)
iceX

Réponses:

12

Question 1) Quel est le besoin d'une classe dans un langage dynamique? Pourquoi le langage est conçu de cette façon pour utiliser une classe comme une sorte de «modèle» au lieu de le faire de la manière prototype et d'utiliser simplement un objet?

Le tout premier langage OO (même s'il ne s'appelait pas "OO"), Simula, n'avait pas d'héritage. L'héritage a été ajouté dans Simula-67, et il était basé sur les classes.

Vers la même époque, Alan Kay a commencé à travailler sur son idée d'un nouveau paradigme de programmation, qu'il a appelé plus tard "Object-Orientation". Il aimait vraiment l'héritage et voulait l'avoir dans sa langue, mais il détestait aussi vraiment les cours. Cependant, il ne pouvait pas trouver un moyen d'avoir l'héritage sans classes, et il a donc décidé qu'il n'aimait pas les classes plus qu'il n'aimait l'héritage et a conçu la première version de Smalltalk, Smalltalk-72 sans classes et donc sans héritage.

Quelques mois plus tard, Dan Ingalls a proposé une conception de classes, où les classes elles-mêmes étaient des objets, à savoir des instances de métaclasses. Alan Kay a trouvé cette conception un peu moins épouvantable que les anciennes, donc Smalltalk-74 a été conçu avec des classes et avec un héritage basé sur les classes.

Après Smalltalk-74, Alan Kay a estimé que Smalltalk allait dans la mauvaise direction et ne représentait pas vraiment ce qu'OO était, et il a proposé que l'équipe abandonne Smalltalk et recommence à zéro, mais il a été mis en minorité. Ainsi ont suivi Smalltalk-76, Smalltalk-80 (la première version de Smalltalk à être mise à la disposition des chercheurs), et enfin Smalltalk-80 V2.0 (la première version à être commercialisée, et la version qui est devenue la base d'ANSI Smalltalk) .

Étant donné que Simula-67 et Smalltalk-80 sont considérés comme les grands-parents de toutes les langues OO, presque toutes les langues qui ont suivi, ont copié aveuglément la conception des classes et l'héritage basé sur les classes. Quelques années plus tard, lorsque d'autres idées comme l'héritage basé sur des mixins au lieu de classes et la délégation basée sur des objets au lieu de l'héritage basé sur des classes ont fait surface, l'héritage basé sur une classe était déjà devenu trop ancré.

Chose intéressante, le langage actuel d'Alan Kay est basé sur la délégation de prototypes.

Jörg W Mittag
la source
"... la langue actuelle d'Alan Kay ..." qui est ...?
Javier
@Javier: Je ne pense pas qu'il ait un nom, et le nom du système ne cesse de changer.
Jörg W Mittag
Cela devrait être une bonne réponse pour indiquer la prochaine fois que quelqu'un inscrira l'héritage comme une exigence pour OO :)
Hey
1
@iceX: Alan Kay a fondé le Viewpoints Research Institute pour travailler sur ses idées. Malheureusement, les informations sont vraiment dispersées sur le site Web.
Jörg W Mittag
3
Alan Kay cite OO: "OOP pour moi ne signifie que la messagerie, la conservation et la protection locales et la dissimulation du processus d'état, et la liaison tardive extrême de toutes choses. Cela peut être fait dans Smalltalk et dans LISP. Il y a peut-être d'autres systèmes dans ce qui est possible, mais je ne les connais pas. "
Joeri Sebrechts
23

De nombreux programmeurs préfèrent travailler avec des classes. C'est un concept très facile à comprendre qui est un bon modèle de processus de pensée humaine sur le monde (c'est-à-dire que nous relions instinctivement les objets réels au groupe abstrait d'éléments auxquels nous considérons qu'ils appartiennent, ce qui est une classe). . De plus, les classes facilitent le raisonnement sur les types d'objets: dans un langage basé sur les classes, l'application de principes comme la substitution de Liskov est plus simple que dans un langage où nous avons juste des objets qui peuvent avoir des méthodes différentes, ou dont le type peut même changer au moment de l'exécution , comme c'est le cas en JavaScript.

Notez que même en JavaScript, énormément de code utilise simplement la fonction prototype pour émuler des classes. C'est principalement parce que beaucoup de programmeurs préfèrent penser de cette façon.

Il existe également une autre raison pour laquelle les langages basés sur les classes sont préférés: il est plus facile de les compiler en code efficace. Les machines virtuelles JavaScript les plus efficaces créent efficacement des classes dynamiques pour représenter les types d'objets JavaScript à mesure que leurs méthodes et prototypes changent. Voir cette description de la mise en œuvre de V8 pour une justification de la raison pour laquelle cela est fait.

Jules
la source
4
Votre dernier paragraphe prend en charge exactement le contraire de ce que vous dites: la V8 prouve que vous n'avez pas besoin de classes dans le langage pour compiler en un code efficace basé sur des classes.
Jörg W Mittag
4
Oui, vous n'en avez pas besoin - mais le fait que V8 (et probablement Self, même si je n'ai pas lu autant de choses sur la conception de ce système) crée efficacement des classes virtuelles signifie que partir d'un langage qui utilise nativement des classes est presque certainement plus facile, et se retrouverait donc probablement avec le JIT devant passer moins de temps à compiler le code.
Jules
11
Bien sûr, et le fait que la V8 crée effectivement des GOTOs et des registres signifie que simplement abandonner toutes les abstractions et écrire directement dans l'assemblage est presque certainement plus facile, et se retrouverait donc probablement avec le JIT devant passer moins de temps à compiler le code. C'est le travail d'un compilateur de prendre en charge les abstractions de niveau supérieur.
Jörg W Mittag
1
Oui, mais c'est un compromis, car l'abstraction de niveau supérieur est dans la plupart des cas plus difficile à implémenter et a souvent une pénalité de performance à l'exécution, en particulier lorsque vous travaillez avec un JIT plutôt qu'avec un compilateur AOT. Je soupçonne que de nombreux concepteurs de langues choisissent une structure basée sur les classes pour l'une ou les deux raisons; Je sais que c'est pourquoi j'ai choisi des classes avec des membres fixes pour la langue (autrement dynamique) sur laquelle je travaille, mais je ne peux que spéculer sur d'autres langues.
Jules
1
Je dirais que la seule façon dont les programmeurs préfèrent "penser en classe" est que c'est ainsi que la plupart d'entre nous apprennent. Je me souviens certainement de beaucoup de mes camarades de collège qui ont eu du mal à saisir et à comprendre des concepts orientés objet vraiment fondamentaux pendant plusieurs années. Cela semble évident et facile avec le recul.
KChaloux
3

J'ai entendu dire que sur de grands projets, où des équipes de personnes travaillent ensemble sur le même code, que les langages flexibles (où vous pouvez modifier les propriétés et les méthodes d'un objet pendant l'exécution) sont des libertés que les autres membres de l'équipe ne veulent pas de vous avoir.

Ils veulent savoir, lorsqu'ils traitent avec un objet, que l'objet agira exactement comme le plan le dit, et non d'une manière morphisée à laquelle un autre développeur ambitieux a décidé de le changer afin de terminer sa propre tâche.

Donc, la seule raison pour laquelle je peux concevoir que quelqu'un ne voudrait pas des flexibilités offertes par ces langages dynamiques impressionnants, c'est qu'il veut simplifier le développement d'équipe, le débogage et l'auto-documentation.

Personnellement, j'ai développé des applications dans les deux méthodologies et je fais avancer les choses beaucoup plus rapidement avec les langages dynamiques. Je n'utilise aucun de ces cadres conçus pour transformer à nouveau mon langage dynamique en un langage basé sur les classes. De telles choses sont une régression à mes goûts.

Lonnie Best
la source
1

Pour moi, la POO signifie uniquement la messagerie, la rétention et la protection locales et la dissimulation du processus étatique, et la liaison tardive extrême de toutes choses - Alan Kay

Donc, ce qu'il dit ici, c'est que OO consiste à créer des boîtes noires qui répondent aux messages. D'une certaine manière, REST est le système OO ultime en ce qu'il utilise des verbes (c'est-à-dire un message) et des ressources (c'est-à-dire une boîte opaque qui contient des données).

Donc, la question de savoir pourquoi certains sont basés sur des classes et d'autres basés sur des prototypes ne tient pas compte du fait que cela n'a pas vraiment d'importance, ce sont tous deux de simples implémentations. Un système qui utilise uniquement la messagerie au lieu d'appels de méthode est tout aussi OO que les deux instances que vous mentionnez.

gbjbaanb
la source