4 ms·
I'll bite. Tooling. The CIDER devs are doing a great job, but Clojure gets to suffer by being tightly coupled to the JVM. Meanwhile CL thought deeply about hav
by blacktriangle 5y ago
I'll bite.
Tooling. The CIDER devs are doing a great job, but Clojure gets to suffer by being tightly coupled to the JVM. Meanwhile CL thought deeply about having a truly dynamic developer experience, for example look at the CL condition system.
Multiparadigm. Sometimes I want an object, sometimes I want goto, sometimes I want to mutate a thing. CL is probably the least opinionated language every made, Clojure is highly opinionated. For a long-term investment, I want to have options.
There's a spec. CL is done. I have faith my code will continue to run as-is well into the future. Hickey very much values long-term backward compatibility and maintenance today, but who knows what he'll value in the future? For that matter what does Clojure look like if he gets hit by a bus? I don't want to have to worry about things like that.
CL has more parens. People love to complain about CL let's excessive parens, but I find them much easier to read, but more importantly they are much easier to work with when using structural editing tools, and easier to work with in macros. I find Clojure's extra syntax for literals to be a net negative.
No JVM. The JVM is a mixed bag, if you need it for operational reasons then its a huge win, but if you're not constrained by somebody else organizational policies, then I think the JVM is a net loss. Instead of dealing with the JVM, CL gives you a variety of tools to tune performance to make your programs scream.
Reader macros. Clojure rejects them as a giant footgun, CL gives them to you since CL is all about maximal power and flexibility for an uncertain future.
- qPM9l3XJrF 5y agoThanks! I'm curious why you think the JVM is a net loss if you don't need it, if you want to elaborate on that.
- lispm 5y agoFor example some Lisps allow us to save the state of the heap to disk easily, incl. the runtime, to make an executable. This is then no special feature, saving is done in a second and starting the executable is also extremely fast. There is no extra tooling needed. That way one does not need to restore the state by loading a bunch of files. The default JVM does not support that. Code is by default compiled to native code -> no JIT needed. The JVM also does not support optimization of tail function calls into jumps. Thus the language either has to implement it in a slower way, provide limited hacks around it or omit that feature. Various Lisps provide full TCO as an optimization feature in the compiler. The JVM is also not optimized to represent Lisp data. For example the numerics of Common Lisp are relatively powerful and thoughtful designed with bignums/fixnums, ratios, complex numbers, etc.. The JVM has its own idea of numeric types and its operations. Common Lisp has CLOS as a very dynamic object system with an optional meta-object system. That maps also not directly to JVM classes/objects (no full multiple inheritance, no multi-methods, no method combinations, ...). One can implement that on top of the JVM, but it will always be slightly slower than a native Lisp implementation. Looking at compiled code / backtraces / ... on the JVM will always look slightly alien to a Lisp programmer - some Lisp implementations have simpler stack traces, tailored for Lisp. The positive side of the JVM is the better integration into the IT landscape, modern garbage collectors, a mature runtime with lots of users and the direct integration into Java/... software on the JVM. If we look at Common Lisp, there is a full implementation of Common Lisp on the JVM called ABCL. That's a great achieve, but native implementations like SBCL are much faster and thus more widely used amongst CL users. SBCL comes with the added bonus of an excellent native code compiler written in Lisp itself. I would recommend the SBCL compiler also for beginners, because it gives a lot of warnings and other information at compile-time.
- filoeleven 5y ago> For example some Lisps allow us to save the state of the heap to disk easily, incl. the runtime, to make an executable. Wait, hang on. Is this feature analogous to Smalltalk’s image-based environment? Does this mean I could run a Lisp REPL and “save all” then “restore all” later? Or is this a subset of what Smalltalk does? Excluding the Smalltalk GUI environment, of course. Asking because that’s the biggest “you must try it to understand the experience” selling point of Smalltalk. Some Lisps (hopefully some of the same ones?) have a really nice interactive debug mode, which IIRC is another Smalltalk selling point. If those are both covered by a single Lisp, I’d like to try that out instead of Smalltalk, because Lisp’s structure makes more sense to me. I am biased towards Clojure because I like its opinionated language design choices irrespective of Java interop. Mainly the seq abstraction and immutable-by-default. A first-class debug REPL and “save / restore the whole runtime environment” are both things I want to examine though.
- diskzero 5y agoYes. Saving to an image, loading the image, modifying the image while the program is running and seeing the program update without recompilation is part of the magic of programming in a good Lisp IDE. Smalltalk was influenced by how Lisp used images and went on to build on the concept of images and do all the other things that make Smalltalk Smalltalk. Various commercial Smalltalks have come and gone over the years. I am assuming you have been looking at either Squeak or Pharo. Both are nice, but the user interface is trapped inside of a windowing system inside of the environment you are executing in. A Pharo program will present a window and inside that window is another desktop environment. This seems unnatural to me, but it is the result of how Smalltalk works; it does everything. If you have the time, you can read about this in the Smalltalk-80 books. LispWorks allows you to use the native widgets of the platform you are targeting. Your program will use native widgets. Clozure CCL (not Clojure) also has native widget support. Take a look at the OpusModus [1] composition program. It is written in Clozure CCL and is very polished, professional application. It sounds like you already understand the philosophical differences between Lisp and Smalltalk. You can use an object system in Lisp, but it is option. Smalltalk is objects all the way down. Lisp can be molded to operate in variety of idioms, so you can create your own opinionated system, but one is not dictated for you. [1] https://www.opusmodus.com/ https://www.opusmodus.com/