5 ms·
As always, lispm given a free lession...
by lerax 8y ago
As always, lispm given a free lession...
- j-pb 8y agoYeah mentioning clojure in a thread where he's active is a surefire way to get downvoted. That guy hates everything not CL...
- lispm 8y agoExperience shows that most Clojure users come from Java and have very little idea about Lisp. It might help to bring in some perspective, since Clojure is not a very typical Lisp: no interpreter, no linked lists as base data structure, no Lisp in Lisp, no Lisp runtime, no images, not the typical debugging tools like break loops, the runtime is from the JVM or another environment (.net, JavaScript), ... Lisp existed already before Clojure and has a rich history, much of which is not in Clojure.
- dig1 8y ago> no interpreter ClojureScript is interpreter, unless you run Closure compiler in compilation phase. Interpretation is done by default in repl. There is also Joker [0]. > no linked lists as base data structure Not true. Linked lists are base data structure on the same level as vectors and hash maps. Unlike Scheme where hash maps are sometimes implemented as assoc-ed lists. > no Lisp in Lisp Check for CinC and derivatives [1] or Ferret [2]. > no Lisp runtime What you define by "runtime"? > no images By this requirement, 90% Lisps out there would not be Lisp ;) Even some Common Lisp implementations (ABCL) doesn't have it. Or if you want another extreme, V8/nodejs can generate image/snapshot or you can dump JVM image via Criu [3]. > not the typical debugging tools like break loops IntelliJ has it, CIDER has it, there is clj-debugger... It is not part of default implementation, just like Scheme doesn't have it. [0] https://joker-lang.org/ https://joker-lang.org/ [1] https://github.com/remleduff/CinC https://github.com/remleduff/CinC [2] https://ferret-lang.org/ https://ferret-lang.org/ [3] https://www.criu.org/Main_Page https://www.criu.org/Main_Page
- lispm 8y ago> ClojureScript is interpreter I thought ClojureScript compiles to JavaScript? > What you define by "runtime"? For example the stuff the JVM provides: memory management, data layout, interrupt handling, threads, loading code, talking to the environment, ... > By this requirement, 90% Lisps out there would not be Lisp I'd think it's more like 70% use images... just a guess. The exceptions usually are Lisps using runtimes which can dump/load images (like probably every Lisp on the JVM) or which by choice don't do (like some Lisp to C compilers, ...). > Even some Common Lisp implementations (ABCL) doesn't have it. That's the same limitation of the JVM. There are a few more implementations which don't have it. But generally there is a rich choice of full language implementations with and without images.
- 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.
- rlander 8y agoYup! As if Clojure users cared about this level of pedantism.
- deleted 8y ago[deleted]