Die kurze Antwort ist, dass Clojure entworfen wurde, um einen sehr einfachen Single-Pass-Compiler zu verwenden, der einen einzelnen s-Ausdruck oder eine Form gleichzeitig liest und kompiliert. Zum Besseren oder Schlechteren gibt es keine globale Typinformation, keine globale Typinferenz und keine globale Analyse oder Optimierung. Clojure verwendet clojure.lang.Var
Instanzen, um globale Bindungen durch eine Reihe von Hashmaps von Textsymbolen zu Transaktionswerten zu erstellen. def
bildet alle Erstellungsbindungen auf globaler Ebene in dieser globalen Bindungszuordnung. Wo also in Scala eine "Funktion" (Methode) zu einer Instanz oder statischen Methode einer gegebenen JVM-Klasse aufgelöst wird, ist in Clojure eine "Funktion" (def) eigentlich nur ein Verweis auf einen Eintrag in der Tabelle der var-Bindungen. Wenn eine Funktion aufgerufen wird, gibt es keine statische Verknüpfung zu einer anderen Klasse, stattdessen wird die Variable durch einen symbolischen Namen referenziert und dann dereferenziert, um eine Instanz eines Objekts zu erhalten, das dann aufgerufen wird.
Diese Indirektionsebene bedeutet, dass es möglich ist, nur eine einzelne Definition gleichzeitig neu zu bewerten, und dass die Neubewertung für alle Clients der neu definierten Variablen global sichtbar wird.
Im Vergleich, wenn sich eine Definition in Scala ändert, muss scalac die geänderte Datei neu laden, macroexpand, type infer, type check und compile. Aufgrund der Semantik des Klassenladens auf der JVM muss scalac auch alle Klassen neu laden, die von Methoden in der Klasse abhängen, die sich geändert hat. Außerdem werden alle Werte, die Instanzen der geänderten Klasse sind, zu Papierkorb.
Beide Ansätze haben ihre Stärken und Schwächen. Offensichtlich ist der Ansatz von Clojure einfacher zu implementieren, aber er zahlt laufende Kosten in Bezug auf die Leistung aufgrund fortlaufender Funktionsnachschlagoperationen, die Korrektheitsbedenken wegen fehlender statischer Typen vergessen und was Sie haben. Dies ist wohl für Kontexte geeignet, in denen viele Änderungen in einem kurzen Zeitrahmen stattfinden (interaktive Entwicklung), ist aber weniger geeignet für Kontext, wenn Code größtenteils statisch ist (Einsatz, daher Oxcart). some work I did schlägt vor, dass die Verlangsamung von Clojure-Programmen aus dem Mangel an statischer Methodenverknüpfung in der Größenordnung von 16-25% liegt. Das heißt nicht Clojure langsam oder Scala schnell zu nennen, sie haben nur unterschiedliche Prioritäten.
Scala entscheidet sich dafür, mehr Arbeit zu leisten, damit die kompilierte Anwendung besser funktioniert, was wohl besser für die Anwendungsbereitstellung geeignet ist, wenn wenig oder gar kein Nachladen stattfindet, aber ein Nachteil ist, wenn Sie viele kleine Änderungen vornehmen wollen .
Einige Materialien, die ich zur Verfügung habe, um Clojure-Code mehr oder weniger cronological durch Veröffentlichungsreihenfolge zu kompilieren, da Nicholas meine GSoC-Arbeit viel beeinflusste.
Was ich lässt mich annehmen, in der unglückliche Ort, einfach zu sagen: "Es tut mir leid, Scala war dafür nicht so konzipiert C ljure war "in Bezug auf Code Hot Swapping.
Einer wird verwendet, um Clojure zu schreiben, der andere um Scala zu schreiben. Auch: http://stackoverflow.com/questions/2471947/is-there-an-easy-way-to-get-the-scala-repl-to-relo-a-class-or-package – vptheron
Es ist ein wenig schwer für mich zu wissen, wie eine richtige Antwort aussehen würde? Fragen Sie vielleicht, ob die Scala REPL Funktionen in einem laufenden Programm neu definieren kann? –
Neugier, die Frage ist gut, aber der Titel ist nicht. – Mars