Eine REPL hat eine ziemlich spezifische Bedeutung. Eine "echte REPL" wäre eine, die dem folgenden Muster entspricht: Eval Print Loop lesen. Man kann eine REPL in clojure in nur wenigen Zeilen bauen:
(loop []
(let [string (read-line)
data (read-string line)
result (eval data)]
(println result)
(recur)))
Hier sehen Sie die wichtigsten Teile eines echten ers. read-line
liest etwas Text von der Konsole. read-string
konvertiert diese Zeichenfolge in Daten (Listen, Vektoren, Zahlen usw.). eval
wertet die Daten aus, die ein Ergebnis zurückgeben, und println
gibt das Ergebnis aus.
Einige würden argumentieren (und ich stimme zu), dass nur solche Systeme, die diesen vier Schritten folgen, qualifiziert werden, ein Replikat genannt zu werden. Und einige würden auch darauf hinweisen, dass Scala nicht homoikonisch ist und daher nicht wirklich eine Replik haben kann.
Mit homoiconic, ich meine, dass der Compiler auf den gleichen Datenstrukturen arbeitet, die vom Leser der Sprache erzeugt und durch die Kernkonstrukte der Sprache manipuliert werden. Zum Beispiel ist dies absolut gültige Clojure Code:
(eval (list (symbol "+") 41 1))) ; evals to 42
Also das ist der Kern der Debatte über „echte“ REPLs. Nur homonische Sprachen wie Lisp (und vielleicht Prolog?) Können echte REPLs haben. Alle anderen sollten wirklich "interaktive Dolmetscher" genannt werden.
Soweit Geschwindigkeit geht. Das liegt wahrscheinlich an der Compiler-Komplexität. Der Clojure-Compiler ist nur etwa 10k Zeilen mit ziemlich linearem Code. Einzelpass, nichts besonderes. Der Scala-Compiler ist ziemlich fortgeschritten und unterstützt Dinge wie statische Typisierung und mehrere Durchgänge. Diese zusätzlichen Funktionen werden in einer Sprache wie Clojure nicht benötigt, und sie neigen dazu, einen Compiler etwas langsamer zu machen.
Hmm. Ich hätte gedacht, dass, wenn eine Befehlszeileninteraktion getrennte Lese-, Auswertungs- und Druckschritte beinhaltet, dies für die REPL-Fähigkeit ausreicht, unabhängig davon, ob die Sprache homoikonisch ist oder nicht. Ich würde etwas nicht als Interpreter bezeichnen, wenn es kompiliert wird, bevor es ausgeführt wird. Natürlich gibt es alle möglichen Zwischenfälle zwischen "einen Ausdruck nacheinander ausführen, einen nach dem anderen" und "große Codeabschnitte übersetzen und optimieren bis auf eine Art" Maschinensprache "und dann ausführen". Aber ich denke nicht, dass irgendetwas davon eine Rolle spielt! – Mars
Related: http://stackoverflow.com/questions/5671214/is-lisp-the-only-language-with-repl –