Warum verwenden viele dynamische Programmiersprachen, die vom Typ Ente stammen, einen klassenbasierten Ansatz anstelle von prototypbasiertem OOP?

23

Da viele dynamische Programmiersprachen die Funktion " Duck Typing" haben und außerdem jederzeit Klassen- oder Instanzmethoden (wie Ruby und Python ) öffnen und ändern können ,…

Frage 1) Was ist für eine Klasse in einer dynamischen Sprache erforderlich? Warum ist die Sprache so konzipiert, dass eine Klasse als eine Art „Vorlage“ verwendet wird, anstatt wie ein Prototyp und nur mit einem Objekt?

Auch JavaScript basiert auf Prototypen, aber CoffeeScript (die erweiterte Version von JavaScript) wählt den klassenbasierten Weg. Dies gilt auch für Lua (basierend auf Prototypen) und MoonScript (basierend auf Klassen). Darüber hinaus gibt es Klasse in ES 6. Also ...

Frage 2) Schlägt es vor, dass Sie, wenn Sie unter anderem versuchen, eine prototypbasierte Sprache zu verbessern, diese in eine klassenbasierte Sprache ändern sollten? Wenn nicht, warum ist es so gestaltet?

iceX
quelle
9
Viele Programmierer wollen sich nicht die Mühe machen, etwas Neues zu lernen. (Es ist zu fremd und "schwierig"). Daher all diese klassenbasierten Bibliotheken und Sprachen, die zu ihnen kompiliert werden.
Thomas Eding
1
Ich stimme Thomas zu, aber was lustig ist, ist, dass, nachdem Sie den dynamischen Ansatz gelernt haben, es tatsächlich einfacher (nicht schwerer) ist. Das Konzept der Objekte ist immer noch da, es ist nur so, dass die Objekte geändert werden können, ohne zuerst einen blöden "Entwurf" neu zu kompilieren. Wenn ich ein fünftes Bein auf einen Stuhl legen möchte, möchte ich nicht erst eine Blaupause ändern müssen, sondern nur das Bein hinzufügen. Dynamische Sprachen bilden meiner Meinung nach die Realität besser ab.
Lonnie Best
1
OOP wurde in einem statisch typisierten Kontext erfunden, in dem Typen deklariert werden müssen. Dort sind Klassen ein sinnvoller Fortschritt gegenüber Datensätzen und Modulen. Prototyp-basiertes OOP war immer nur ein interessantes Forschungsthema für die Self-Sprache und hat es irgendwie in JavaScript geschafft, als einfachste Möglichkeit, das Schlagwort „OOP“ für eine im Wesentlichen funktionale Sprache abzuhaken. Das Schöne ist, dass Sie Klassen über Prototypen implementieren können. Während ich Metaobjekte mag, erleichtert das Trennen von Klassen von ihren Instanzen das Schreiben von gut faktorisiertem, einfachem, lose gekoppeltem Code.
amon
3
Das Wichtigste zuerst: JavaScript selbst unterstützt das classSchlüsselwort ab dem nächsten ECMAScript-Standard (ECMAScript 6). Die Unterstützung von JavaScript-Klassen ist seit langem geplant. Nun, was es ist - Klassen sind nur syntaktischer Zucker, was das Nachdenken über Modelle für Objekte des gleichen Typs erleichtert. Dies ist in JS und in Python und anderen dynamischen Sprachen der Fall.
Benjamin Gruenbaum
1
@BenjaminGruenbaum "... Klassen sind nur syntaktischer Zucker ..." Wow, das ist eine ziemlich neue Idee für mich. Für Sprachen wie Ruby und Python ist es anscheinend egal, ob man ein Objekt verwendet oder Klasse als Vorlage - beide können ohnehin im laufenden Betrieb geändert werden. Und es spielt auch keine Rolle, wie sie mit der Vererbung umgehen. Vielleicht besteht für eine dynamische Sprache keine Notwendigkeit, zwischen dem klassenbasierten Ansatz und dem prototypbasierten Ansatz zu unterscheiden :)
iceX

Antworten:

12

Frage 1) Was ist für eine Klasse in einer dynamischen Sprache erforderlich? Warum ist die Sprache so konzipiert, dass eine Klasse als eine Art „Vorlage“ verwendet wird, anstatt es auf prototypische Weise zu tun und nur ein Objekt zu verwenden?

Die allererste OO-Sprache (obwohl sie nicht "OO" genannt wurde), Simula, hatte keine Vererbung. Vererbung wurde in Simula-67 hinzugefügt und basierte auf Klassen.

Etwa zur gleichen Zeit begann Alan Kay an seiner Idee eines neuen Programmierparadigmas zu arbeiten, das er später "Objektorientierung" nannte. Er mochte Vererbung sehr und wollte sie in seiner Sprache haben, aber er mochte auch keinen Unterricht. Er konnte jedoch keine Möglichkeit finden, eine Vererbung ohne Klassen zu haben, und entschied, dass er Klassen nicht so sehr mochte, als dass er sie mochte, und entwarf die erste Version von Smalltalk, Smalltalk-72 ohne Klassen und somit ohne Vererbung.

Ein paar Monate später entwickelte Dan Ingalls eine Klassenkonstruktion, bei der die Klassen selbst Objekte waren, nämlich Instanzen von Metaklassen. Alan Kay fand dieses Design etwas weniger ansprechend als die älteren, daher wurde Smalltalk-74 mit Klassen und einer auf Klassen basierenden Vererbung entworfen.

Nach Smalltalk-74 hatte Alan Kay das Gefühl, dass Smalltalk sich in die falsche Richtung bewegte und nicht wirklich darstellte, worum es bei OO ging. Er schlug vor, dass das Team Smalltalk aufgibt und neu anfängt, aber er wurde überstimmt. So folgten Smalltalk-76, Smalltalk-80 (die erste für Forscher freigegebene Version von Smalltalk) und schließlich Smalltalk-80 V2.0 (die erste kommerziell freigegebene Version und die Version, die die Grundlage für ANSI Smalltalk wurde). .

Da Simula-67 und Smalltalk-80 die Großeltern aller OO-Sprachen sind, kopierten fast alle folgenden Sprachen blind das Design von Klassen und die Vererbung basierend auf Klassen. Ein paar Jahre später, als andere Ideen wie die Vererbung auf Basis von Mixins anstelle von Klassen und die Delegierung auf Basis von Objekten anstelle von Vererbung auf Basis von Klassen auftauchten, war die klassenbasierte Vererbung bereits zu tief verwurzelt.

Interessanterweise basiert die aktuelle Sprache von Alan Kay auf der Delegation von Prototypen.

Jörg W. Mittag
quelle
"... Alan Kays aktuelle Sprache ..." Was ist ...?
Javier
@Javier: Ich glaube nicht, dass es einen Namen hat und der Name des Systems ändert sich ständig.
Jörg W Mittag
Dies sollte eine gute Antwort sein, um auf das nächste Mal hinzuweisen, wenn jemand die Vererbung als Voraussetzung für OO auflistet :)
Hey,
1
@iceX: Alan Kay gründete das Viewpoints Research Institute , um an seinen Ideen zu arbeiten. Leider sind die Informationen auf der Website sehr verstreut.
Jörg W Mittag
3
Alan Kay zitiert zu OO: "OOP bedeutet für mich nur Nachrichtenübermittlung, lokale Speicherung und Schutz sowie das Verbergen von Statusprozessen und extrem spätes Binden aller Dinge. Dies kann in Smalltalk und in LISP erfolgen. Möglicherweise gibt es andere Systeme in das ist möglich, aber ich bin mir dessen nicht bewusst. "
Joeri Sebrechts,
23

Viele Programmierer arbeiten lieber mit Klassen. Es ist ein sehr einfach zu verstehendes Konzept, das ein gutes Modell menschlicher Denkprozesse über die Welt darstellt (dh wir beziehen reale Objekte instinktiv auf die abstrakte Gruppe von Gegenständen, zu denen wir sie als gehören betrachten, was eine Klasse ist). . Klassen vereinfachen auch das Denken über Objekttypen: In einer klassenbasierten Sprache ist das Anwenden von Prinzipien wie der Liskov-Substitution einfacher als in einer Sprache, in der es nur Objekte gibt, die möglicherweise andere Methoden haben oder deren Typ sich sogar zur Laufzeit ändert , wie es in JavaScript der Fall ist.

Beachten Sie, dass selbst in JavaScript sehr viel Code einfach die Prototypfunktion verwendet, um Klassen zu emulieren. Dies liegt hauptsächlich daran, dass viele Programmierer es vorziehen, so zu denken.

Es gibt noch einen weiteren Grund, warum klassenbasierte Sprachen bevorzugt werden: Es ist einfacher, sie zu effizientem Code zu kompilieren. Die effizientesten JavaScript-VMs erstellen effektiv dynamisch Klassen, um die Typen von JavaScript-Objekten darzustellen, wenn sich ihre Methoden und Prototypen ändern. In dieser Beschreibung der Implementierung von V8 finden Sie eine Begründung, warum dies so ist.

Jules
quelle
4
Ihr letzter Absatz unterstützt genau das Gegenteil von dem, was Sie sagen: V8 beweist, dass Sie keine Klassen in der Sprache benötigen, um effizienten klassenbasierten Code zu kompilieren.
Jörg W Mittag
4
Ja, Sie brauchen sie nicht - aber die Tatsache, dass V8 (und vermutlich Self, obwohl ich nicht so viel über das Design dieses Systems gelesen habe) virtuelle Klassen effektiv erstellt, bedeutet, dass man von einer Sprache ausgeht, die von Haus aus Klassen verwendet sicherlich einfacher und würde daher wahrscheinlich dazu führen, dass die JIT weniger Zeit für das Kompilieren des Codes benötigt.
Jules
11
Sicher, und die Tatsache, dass V8 effektiv GOTOs und Register erstellt, bedeutet, dass es mit ziemlicher Sicherheit einfacher ist, alle Abstraktionen aufzugeben und direkt in Assembler zu schreiben. Daher müsste die JIT wahrscheinlich weniger Zeit für das Kompilieren des Codes aufwenden. Es ist die Aufgabe eines Compilers, übergeordnete Abstraktionen zu unterstützen.
Jörg W Mittag
1
Ja, aber es ist ein Kompromiss, da die Abstraktion auf höherer Ebene in den meisten Fällen schwieriger zu implementieren ist und häufig einen Leistungsverlust zur Laufzeit hat, insbesondere wenn mit einer JIT und nicht mit einem AOT-Compiler gearbeitet wird. Ich vermute, dass viele Sprachdesigner aus einem oder beiden Gründen eine klassenbasierte Struktur wählen. Ich weiß, deshalb habe ich Klassen mit festen Mitgliedern für die (ansonsten dynamische) Sprache ausgewählt, an der ich arbeite, kann aber nur über andere Sprachen spekulieren.
Jules
1
Ich würde argumentieren, dass die einzige Art und Weise, wie Programmierer das "Denken in Klassen" bevorzugen, darin besteht, dass die meisten von uns so unterrichtet werden. Ich kann mich definitiv an viele meiner Kommilitonen erinnern, die einige Jahre lang Probleme hatten, einige wirklich grundlegende objektorientierte Konzepte zu verstehen. Dies scheint nur im Nachhinein offensichtlich und einfach zu sein.
KChaloux
3

Ich habe gehört, dass in großen Projekten, in denen Teams an demselben Code arbeiten, flexible Sprachen (in denen Sie die Eigenschaften und Methoden eines Objekts zur Laufzeit ändern können) Freiheiten sind, die andere Teammitglieder nicht möchten haben.

Sie möchten wissen, dass sich das Objekt so verhält, wie es der Bauplan vorgibt, und nicht auf eine Weise, die ein anderer ambitionierter Entwickler beschlossen hat, es zu ändern, um seine eigene Aufgabe zu erfüllen.

Der einzige Grund, warum ich mir vorstellen kann, dass jemand die Flexibilität dieser beeindruckenden dynamischen Sprachen nicht möchte, ist, dass er die Teamentwicklung, das Debuggen und die automatische Dokumentation vereinfachen möchte.

Persönlich habe ich Anwendungen in beiden Methoden entwickelt, und mit dynamischen Sprachen kann ich vieles schneller erledigen. Ich verwende keines dieser Frameworks, um meine dynamische Sprache wieder in eine klassenbasierte Sprache umzuwandeln. Solche Dinge sind eine Regression nach meinem Geschmack.

Lonnie Best
quelle
1

OOP bedeutet für mich nur Nachrichtenübermittlung, lokale Aufbewahrung und Schutz sowie das Verstecken von staatlichen Prozessen und extrem spätes Binden aller Dinge - Alan Kay

Also, was er hier sagt, ist, dass es bei OO darum geht, Black Boxes zu erstellen, die auf Nachrichten reagieren. In gewisser Weise ist REST das ultimative OO-System, da es Verben (dh eine Nachricht) und Ressourcen (dh ein undurchsichtiges Feld, das einige Daten enthält) verwendet.

Die Frage, warum manche auf Klassen und andere auf Prototypen basieren, geht dahin, dass es eigentlich egal ist, sie sind beide nur Implementierungen. Ein System, das nur Messaging anstelle von Methodenaufrufen verwendet, ist genauso gut wie die beiden von Ihnen erwähnten Instanzen.

gbjbaanb
quelle