JVM unterstützt so viele andere Sprachen als Java wie Groovy,Clojure,Scala
etc, die andere funktionale Sprachen als Java sind (ich beziehe mich auf Java vor Version 8, wo sie Lambda's
nicht unterstützt werden), die keine funktionalen Fähigkeiten unterstützen können sowohl objektorientierte als auch funktionale Sprachen unterstützen?
java
programming-languages
object-oriented
functional-programming
jvm
Aussenseiter
quelle
quelle
Antworten:
Im Vergleich zu anderen VMs ist die JVM nicht besonders vielseitig . Es unterstützt direkt statisch typisierte OO. Für alles andere müssen Sie sehen, welche Teile Sie verwenden können und wie Sie alles andere aufbauen können, das Ihre Sprache über diesen Teilen benötigt.
Bis Java 7 den
invokedynamic
Bytecode einführte , war es beispielsweise sehr schwierig, eine dynamisch typisierte OO-Sprache in der JVM zu implementieren. Sie mussten komplexe Problemumgehungen verwenden, die die Leistung beeinträchtigten und zu fürchterlich aufgeblähten Stack-Traces führten.Davor waren jedoch einige dynamische Sprachen (Groovy, Jython, JRuby ua) in der JVM implementiert.
Nicht, weil die JVM so vielseitig ist, sondern weil sie so weit verbreitet ist und sehr ausgereifte, gut unterstützte und leistungsstarke Implementierungen aufweist.
Und, vielleicht noch wichtiger, weil es eine riesige Menge von Java-Code gibt, die so ziemlich alles macht, und wenn Ihre Sprache in der JVM ausgeführt wird, können Sie leicht Funktionen anbieten, die sich in diesen Code integrieren lassen. Grundsätzlich ist es die Version des 21. Jahrhunderts, die Interoperabilität mit C bietet, wenn Ihre Sprache in der JVM ausgeführt wird.
quelle
Die JVM wurde so geschrieben, dass sie sich im Grunde genommen wie eine CPU verhält. Es gibt eine Reihe von Anweisungen, ähnlich einer Assembly, die von der VM ausgeführt werden und Bytecodes genannt werden. Wenn Sie einen Compiler schreiben können, der einen gültigen Satz von Bytecodes generiert, kann die JVM diese ausführen.
Wikipedia hat eine Liste der Bytecodes:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
sowie eine Erklärung, wie die JVM die Byte-Codes lädt:
http://en.wikipedia.org/wiki/Java_virtual_machine
Durch die Verwendung der aufrufbaren Bytecodes kann eine funktionale Sprache Code ausführen, unabhängig davon, wie die Quelle aussieht. Darüber hinaus haben Sprachimplementierungen wie jruby durch die Hinzufügung von invokevirtual eine gewisse Flexibilität hinsichtlich ihrer Funktionsweise verliehen.
quelle
Ich füge hinzu, dass die JVM ein gut definiertes und anständiges Speichermodell ( JMM ) unterstützt, was eine gute Unterstützung für konsistentes Threading-Verhalten (wenn auch auf niedriger Ebene) bedeutet. Es hat auch einen leistungsstarken Just In Time- Compiler (nicht mehr nützlich für dynamische Sprachen dank MethodHandles und invokedynamic).
Last but not least gibt es das Garbage Collection-Subsystem der JVM , das (mit der richtigen Abstimmung) den Arbeitsspeicher für Sie verwaltet, unabhängig von der Sprache, in der Sie sich befinden.
quelle
someField = new int[]{42};
, mit der ich sicherstellen kann, dass jeder Thread, der das neue Array sieht, den Wert sieht 42 sollen entweder das Feld machenfinal
odervolatile
. Wenn das Feld träge generiert wird, auf das jedoch häufig zugegriffenfinal
wird, funktioniert es nicht und esvolatile
kann bei jedem Zugriff zu einer unnötigen Synchronisationsstrafe führen. In selbst dem lockersten .NET-Modell ...Das Schlüsselelement dabei ist die Trennung der Kompilierung von der Ausführungsphase. Auf diese Weise ist es möglich, andere Compiler zu schreiben, die andere Sprachen zu Bytecode kompilieren.
Bytecode dort verhält sich ähnlich wie der Maschinencode einer CPU - Sie haben alle kleinen Operationen, die zum Ausführen eines Programms erforderlich sind - Sie können eine Variable abrufen, rechnen, bedingte Operationen ausführen usw.
Java ist auch nichts Besonderes. In Java war das Vorhandensein mehrerer Sprachen im Gegensatz zu anderen VMs nicht einmal ein Entwurfsziel. Für Microsoft .Net CIL war die Möglichkeit, mehrere Sprachen (C #, VB.Net, ...) auszuführen, ein wichtiges Designelement, und auch ParrotVM aus dem Perl6-Projekt sollte eine generische VM sein.
Zum Spaß habe ich mal einen Beweis erstellt, dass selbst die Zend Engine von PHP das zulässt.
Und ehrlich gesagt ist dies nichts Neues - selbst auf echter Hardware können Sie mehrere Sprachen ausführen - z. B. C oder Fortran.
Der Unterschied zu dieser Trennung von Kompilierung und Ausführung besteht darin, dass CLSSIC-Interpreter, wie einige Formen von Basic, Shell-Skripten usw., häufig so arbeiten, dass sie Code mehr oder weniger zeilenweise ausführen, ohne ihn in eine unmittelbare Form zu bringen zwischen.
quelle
Die JVM ist die erste virtuelle Maschine, deren kombinierte Speicherbereinigung, Leistung und funktionsfähiges Sandbox-Modell ich kenne. Die Entstehung vieler Sprachen zur Unterstützung der JVM ist wahrscheinlich weniger auf ihre "Vielseitigkeit" zurückzuführen, sondern vielmehr auf die Tatsache, dass der Java-Sprache einige wichtige Funktionen fehlen, die die Benutzer in einer Programmiersprache wünschen. Während die meisten Maschinensprachen nur etwa ein halbes Dutzend Datentypen haben (z. B. Byte, Halbwort, Wort, Doppelwort, Gleitkomma mit einfacher Genauigkeit und Gleitkomma mit doppelter Genauigkeit), lässt die überwiegende Mehrheit der Programmiersprachen die Verwendung von Code zu eine beliebige Anzahl von benutzerdefinierten Datentypen. Die JVM erkennt einige primitive Typen, die denen einer typischen Maschine ähneln, sowie einen weiteren Typ: die Promiscuous Object Reference. Die Java-Sprache erkennt ebenfalls diese Grundelemente, und Promiscuous Object Referenzen. Während eine Variable möglicherweise darauf beschränkt ist, keine Verweise auf Objekte zu speichern, die nicht zu einer bestimmten Klasse gehören, unterscheidet die Sprache nicht zwischen den folgenden Typen von Typfeldern
List<String>
das könnte von Instanz stattMyThing
KlasseMyClass
:Ein Verweis auf etwas Code ist eine unveränderliche Implementierung von
List<String>
Ein Verweis auf eine Instanz eines veränderlichen Listentyps, der niemals einem Objekt ausgesetzt wird, das ihn möglicherweise verändert.
Ein Verweis auf eine veränderbare Liste, auf die, außer während der Ausführung der
MyThings
Methoden, möglicherweise nirgendwo im Universum ein anderer Verweis existieren könnte.Ein Verweis auf eine veränderbare Liste, die einem anderen Objekt gehört , das dieses andere Objekt
MyThing
auf irgendeine Weise verwenden möchte .Ein Verweis auf eine veränderbare Liste, die
MyThing
Eigentümer ist, die aber auch anderen Objekten ausgesetzt wurde, damit sie etwas damit anfangen können.Obwohl all diese Felder einen Typ haben könnten
List<String>
, enthalten sie sehr unterschiedliche Dinge. Eine expressive Sprache könnte eine Unterscheidung zwischen diesen Bedeutungen ermöglichen, Java jedoch nicht. Da eine Sprache solchen Dingen (zumindest außerhalb allgemeiner Kontexte) Bedeutung beimessen und auf der JVM ausgeführt werden kann, bleibt für JVM-Zielsprachen viel Raum, um Konzepte auszudrücken, die Java nicht ausdrücken kann.quelle