2015-05-22 23 views
5

ho cercato di eseguire due funzioni fattoriali con lo stesso algoritmo, uno in Scala, l'altro in Clojure:Differenza tra Scala REPL e Clojure REPL - compilare velocità

// Scala: 
def factorial(n:Int) = (1 to n).foldLeft(1: BigInt)(_*_) 

-

;; Clojure: 
(defn factorial [x] 
    (reduce * (range 1N (inc x)))) 

La prima volta che inserisco la funzione nel REPL, il Clojure valuta (definizione della funzione, non calcolando fattoriale) senza alcun ritardo evidente; mentre quello di scala si fermava solo per un breve periodo. (Anche se molto, molto breve, ancora visibile.)

Quando si applica la funzione per calcolare il fattoriale, entrambi restituiscono il risultato molto velocemente.

Vorrei ottenere una conoscenza di base sulla REPL. C'è qualche differenza tra i due REPL? Scala REPL è un vero REPL?

risposta

10

Un REPL ha un significato piuttosto specifico. Un "REPL reale" sarebbe uno che si adatta allo schema seguente: Leggi Eval Print Loop. Si può costruire un REPL in clojure in poche righe:

(loop [] 
    (let [string (read-line) 
     data (read-string line) 
     result (eval data)] 
    (println result) 
    (recur))) 

Qui sotto potete vedere le parti principali di un vero e proprio repl. read-line legge del testo dalla console. read-string converte quella stringa in dati (liste, vettori, numeri, ecc.). eval valuta i dati che restituiscono un risultato e println stampa il risultato.

Alcuni sostengono (e sono d'accordo) che solo quei sistemi che seguono questi quattro passi si qualificano per essere chiamati repl. E alcuni potrebbero anche sottolineare che Scala non è omoiconico, e quindi non può davvero avere un repl.

Per omoiconico, intendo che il compilatore opera sulle stesse strutture dati prodotte dal lettore del linguaggio e manipolate dai costrutti principali del linguaggio. Ad esempio, questo è perfettamente valido codice Clojure:

(eval (list (symbol "+") 41 1))) ; evals to 42 

Ecco, questo è il succo del dibattito sulla REPLs "reali". Solo i linguaggi omoiconici come il lisp (e forse il prologo?) Possono avere REPL veri. Tutti gli altri dovrebbero essere chiamati "interpreti interattivi".

Per quanto riguarda la velocità. Probabilmente è dovuto alla complessità del compilatore. Il compilatore Clojure si trova a circa 10.000 linee di codice piuttosto lineare. Passaggio singolo, niente di speciale. Il compilatore Scala è piuttosto avanzato, supportando cose come la tipizzazione statica e più passaggi. Queste funzionalità extra non sono necessarie in un linguaggio come Clojure e tendono a rallentare un compilatore un po '.

+1

Hmm. Avrei pensato che se un'interazione a riga di comando comportava fasi di lettura, valutazione e stampa separate, ciò sarebbe sufficiente per REPL-ness, indipendentemente dal fatto che la lingua sia o meno omoiconica. Non chiamerei qualcosa di un interprete se si sta compilando prima dell'esecuzione. Ovviamente, ci sono tutti i tipi di casi intermedi tra "eseguire un'espressione alla volta, uno dopo l'altro" e "tradurre e ottimizzare pezzi di codice di grandi dimensioni in una sorta di linguaggio" macchina ", quindi eseguire". Tuttavia, non penso che tutto ciò sia importante! – Mars

+0

correlati: http://stackoverflow.com/questions/5671214/is-lisp-the-only-language-with-repl –