Che cosa rende JVM così versatile da supportare così tante lingue JVM?

18

JVM supporta così tante lingue diverse da Java come Groovy,Clojure,Scala etc che sono lingue funzionali diverse da Java (mi riferisco a Java prima della versione 8 dove Lambda's non è supportato) che non supporta funzionalità funzionali. Ad un alto livello, cosa rende la JVM così versatile da supportare sia linguaggi orientati agli oggetti che funzionali?

    
posta Geek 14.07.2013 - 10:23
fonte

5 risposte

36

Rispetto ad altre macchine virtuali, la JVM in realtà non è particolarmente versatile . Supporta direttamente OO staticamente digitato. Per tutto il resto, devi vedere quali parti puoi utilizzare e come puoi costruire tutto il resto del tuo linguaggio in più rispetto a quelle parti.

Ad esempio, fino a quando Java 7 ha introdotto il bytecode invokedynamic , è stato molto difficile implementare un linguaggio OO dinamicamente tipizzato sulla JVM: è stato necessario utilizzare soluzioni alternative che erano dannose per le prestazioni e hanno provocato tracce di stack orribilmente gonfiate.

Eppure, un gruppo di linguaggi dinamici (Groovy, Jython, JRuby tra gli altri) sono stati implementati sulla JVM prima di quello.

Non perché la JVM sia così versatile, ma perché è così diffusa e perché ha implementazioni molto mature, ben supportate e ad alte prestazioni.

E, forse ancora più importante, perché c'è un'enorme quantità di codice Java là fuori che fa praticamente qualsiasi cosa, e se la tua lingua funziona sulla JVM, puoi facilmente offrire servizi per l'integrazione con quel codice. Fondamentalmente, avere la tua lingua eseguita sulla JVM è la versione del 21 ° secolo di offrire interoperabilità con C.

    
risposta data 14.07.2013 - 11:00
fonte
4

La JVM è stata scritta per funzionare fondamentalmente come una CPU, c'è una serie di istruzioni, un po 'come un assemblaggio, che la macchina virtuale esegue chiamati bytecode. Se puoi scrivere un compilatore che genera un insieme valido di bytecode, allora la JVM può eseguirli.

Wikipedia ha una lista dei bytecode:

link

e una spiegazione di come la JVM carica i codici byte:

link

Usando i bytecodes di stile invoke, un linguaggio funzionale può eseguire codice, indipendentemente da come appare la sorgente. Inoltre, con l'aggiunta di invokevirtual, le implementazioni linguistiche come jruby hanno dato una certa flessibilità con il modo in cui vengono eseguite.

    
risposta data 14.07.2013 - 10:30
fonte
2

Aggiungerò che la JVM supporta un modello di memoria ben definito e abbastanza decente ( JMM ) che significa un buon supporto per un comportamento di threading costante (anche se di basso livello). Ha anche un potente Just In Time compilatore (non più utile per i linguaggi dinamici grazie a MethodHandles e invokedynamic).

Ultimo ma non meno importante è il sottosistema di raccolta di dati inutili della JVM della JVM. che (con la sintonia corretta) gestisce la memoria per te indipendentemente dalla lingua in alto.

    
risposta data 14.07.2013 - 15:57
fonte
1

L'elemento chiave in questo è la separazione della compilazione dalla fase di esecuzione. In questo modo è possibile scrivere altri compilatori compilando altri codici in bytecode.

Il bytecode agisce in modo simile al codice macchina di una CPU - hai tutte le piccole operazioni necessarie per eseguire un programma - puoi ottenere una variabile, fare calcoli matematici, avere operazioni condizionali ecc.

Anche Java non è speciale. In Java l'esistenza di più lingue non era nemmeno un obiettivo di progettazione, a differenza di altre macchine virtuali. Per Microsoft .Net CIL la possibilità di eseguire più lingue (C #, VB.Net, ...) era un progetto chiave elemento, anche il ParrotVM del progetto Perl6 intendeva essere una VM generica.

Per divertirmi ho creato una una prova che anche il motore Zend di PHP avrebbe consentito.

E francamente questo non è niente di nuovo - anche su hardware reale puoi eseguire più lingue - C o Fortran.

La differenza con questa separazione dalla compilazione e dall'esecuzione sono interpreti clssici, come alcune forme di Basic, script di shell, ecc. spesso funzionano in modo che eseguano il codice più o meno in modo riga per riga senza portarlo in una forma immediata in mezzo.

    
risposta data 14.07.2013 - 12:28
fonte
1

La JVM è la prima macchina virtuale di cui sono a conoscenza quali garbage collection, prestazioni e un modello sandbox funzionante. L'emergere di molti linguaggi a supporto della JVM probabilmente non dipende tanto dalla sua "versatilità", quanto piuttosto dal fatto che nella lingua Java mancano alcune caratteristiche significative che le persone vogliono in un linguaggio di programmazione. Ad esempio, mentre la maggior parte dei linguaggi macchina ha solo una mezza dozzina di tipi di dati (ad es. Byte, halfword, word, double word, float a precisione singola e float a precisione doppia), la maggior parte dei linguaggi di programmazione consente l'utilizzo del codice un numero arbitrario di tipi di dati definiti dall'utente. La JVM riconosce alcuni tipi primitivi simili a quelli di una macchina tipica, più un altro tipo: il Riferimento oggetto promiscuo. Il linguaggio Java riconosce anche quelle primitive e riferimenti agli oggetti promiscui. Mentre una variabile può essere vincolata a non mantenere riferimenti a qualcosa che non è una particolare classe, il linguaggio non fa distinzioni tra nessuno dei seguenti tipi di campi di tipo List<String> che potrebbero essere trattenuti dall'istanza MyThing class MyClass :

  • Un riferimento a qualcosa di codice che sa essere un'implementazione immutabile di List<String>

  • Un riferimento a un'istanza di un tipo di elenco mutabile che non sarà mai esposto a qualcosa che potrebbe mutarlo.

  • Un riferimento a un elenco mutabile a cui, tranne durante l'esecuzione dei metodi di MyThings , nessun altro riferimento potrebbe esistere in qualsiasi parte dell'universo.

  • Un riferimento a una lista mutabile che è di proprietà di qualche altro oggetto , che quell'altro oggetto vorrebbe MyThing da usare in qualche modo.

  • Un riferimento a un elenco mutabile che MyThing possiede, ma che ha anche esposto ad alcuni altri oggetti in modo che possano fare qualcosa con esso.

Anche se tutti questi campi potrebbero avere tipo List<String> , contengono cose molto diverse. Un linguaggio espressivo potrebbe consentire una distinzione tra quei significati, ma Java no. Dal momento che una lingua potrebbe attribuire un significato a queste cose (almeno al di fuori dei contesti generici) ed essere eseguita sulla JVM, lascia molto spazio ai linguaggi targettizzati da JVM per esprimere concetti che Java non può.

    
risposta data 28.07.2013 - 20:58
fonte