3 ms·
> I thought ClojureScript compiles to JavaScript? According to [0], these days it is hard to distinguish between compilers/interpreters. However, it translates
by dig1 8y ago
> I thought ClojureScript compiles to JavaScript?
According to [0], these days it is hard to distinguish between compilers/interpreters. However, it translates code to javascript and execute it immediately, just like python does (converting code to own bytecode, before execution). No translation to machine language.
> For example the stuff the JVM provides...
I still fail to see what (Common) Lisp runtime gives over JVM, except direct translation to machine language (Hotspot does that in runtime) and maybe restarts - there are few clojure libraries which implements this, but thing would be much better if is baked in language/jvm.
> I'd think it's more like 70% use images
If you count into that Scheme implementations, that number would be significantly different ;)
[0] https://en.wikipedia.org/wiki/Interpreted_language https://en.wikipedia.org/wiki/Interpreted_language
- lispm 8y agoIn Lisp an interpreter means something slightly different: it means an interpreter for s-expressions. It's not about a virtual machine interpreter or similar. A Lisp interpreter runs directly the s-expressions. This is independent from the idea of evaluation. Evaluation could be implemented by an interpreter or by a compiler. For example using an interpreter: CL-USER 32 > (defun fak (n) (if (zerop n) 1 (* n (fak (1- n))))) FAK Let's break into the function if the argument N is 0: CL-USER 33 > (trace (fak :break (eql (first *traced-arglist*) 0))) (FAK) CL-USER 34 > (fak 5) 0 FAK > ... >> N : 5 1 FAK > ... >> N : 4 2 FAK > ... >> N : 3 3 FAK > ... >> N : 2 4 FAK > ... >> N : 1 5 FAK > ... >> N : 0 Break on entry to FAK with *TRACED-ARGLIST* (0). 1 (continue) Return from break. 2 Continue with trace removed. 3 Continue traced with break removed. 4 Continue and break when this function returns. 5 (abort) Return to top loop level 0. Type :b for backtrace or :c <option number> to proceed. Type :bug-form "<subject>" for a bug report template or :? for other options. CL-USER 35 : 1 > :bq FAK <- FAK <- FAK <- FAK <- FAK <- EVAL <- CAPI::CAPI-TOP-LEVEL-FUNCTION <- CAPI::INTERACTIVE-PANE-TOP-LOOP <- MP::PROCESS-SG-FUNCTION CL-USER 36 : 1 > :n Interpreted call to FAK CL-USER 37 : 1 > :lambda (LAMBDA (N) (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 41B01C37FB>)) (DECLARE (LAMBDA-NAME FAK)) (IF (ZEROP N) 1 (* N (FAK #)))) You see above the actual s-expression being executed for that stack frame. It's not executing any compiled or translated code. It's actually interpreting the source directly without any such step. If we want, we could inspect, alter it with the usual Lisp functions and continue running. CL-USER 39 : 1 > (fifth *) (IF (ZEROP N) 1 (* N (FAK (1- N)))) CL-USER 40 : 1 > (setf (third *) 2) 2 CL-USER 41 : 1 > ** (IF (ZEROP N) 2 (* N (FAK (1- N)))) CL-USER 42 : 1 > :c 1 5 FAK < ... << VALUE-0 : 2 4 FAK < ... << VALUE-0 : 2 3 FAK < ... << VALUE-0 : 4 2 FAK < ... << VALUE-0 : 12 1 FAK < ... << VALUE-0 : 48 0 FAK < ... << VALUE-0 : 240 240 > I still fail to see what (Common) Lisp runtime gives over JVM More efficient data representation, more efficient execution, saving and loading of images, tailored GCs, mixing compiled and interpreted (see above) Lisp code, deeper runtime inspection, resumeable exceptions, efficient stack traces, efficient function calls, fast startup times, etc etc. Something like Lisp, which may have a bunch of very dynamic parts, is hard to implement efficiently on the JVM. Clojure is designed to map better to the JVM.