CL must have some unique appeal that I'm missing. It's community seems to praise it's properties, but is rather quiet otherwise: Interesting talks, projects and companies are be eluding me, especially when compared to the above two Lisps.
CL must have some unique appeal that I'm missing. It's community seems to praise it's properties, but is rather quiet otherwise: Interesting talks, projects and companies are be eluding me, especially when compared to the above two Lisps.
It's also the reason I could never really enjoy CL (or lisps in general): everybody basically ends up using their own dialect of Lisp with their own idiosyncrasies. Some people love the "loop" macro and use it everywhere, some others thing it's ugly and use the equally powerful but syntactically very different "do" construct instead. You can look at some lisp code and have no idea of what it does if you don't expand a few layers of macros first.
That can be true of any language of course, you can abuse overloading, references and macros in C++ if you want, but Lisp really pushes it to the limit in my experience.
Beyond that there's also the problem that the ecosystem is not quite as developed as other more mainstream scripting languages. It doesn't help that the community is split across half a dozen lisp/scheme implementations with often incompatible packages. Do you want to use SBCL? Chicken Scheme? Racket? Guile? Emacs lisp? CLISP? ECL?
I've not once expanded a macro in order to see what it does. The only reason I can think of that one would do that is to see how it works, but one also has to look at e.g. the definition of a function to see how that function works, and that should almost never be important. How are macros different? Just like functions, one often has to read the documentation to know how to use a macro, but I'm not sure how being a macro makes (loop for i from min to max do ...) harder to read than a function would be.
(loop repeat 10
for x = (random 100)
if (evenp x)
collect x into evens
else
collect x into odds
finally (return (values evens odds)))
This macro is actually fairly well designed, so you can guess what all of this does just by interpreting the names (assuming that you understand English well at least) but it's barely Lisp. Just figuring out what parts of this call are keywords and what part are just normal symbols is hard to figure out.(return ...) looks like a function call, but I don't think it is(?). Is collect a loop-ism or can I replace it by any function name? I think it's the former. Is "into" just here to make grammatical sense or are there other keywords I can use here? If `evens` and `odds` already exist as variable names outside of the loop, will they be used or is it a new local binding? If it is a local binding, how do I tell it to use some existing variable name instead?
Basically it's like printf format strings, it's a language within a language, and idiomatic Common Lisp is often full of that stuff in my experience.
That's to be expected with a DSL, isn't it? It's almost the definition.
But I think you're right. The point of a DSL is to change the language to something that you find more useful for what you're trying to do. The downside is that you've changed the language, and now people don't know what to expect unless they're very familiar with your DSL.
If you use the term "scripting language" as an indication, that Common Lisp is interpreted (it is often used in such context) - that is not true - language can't be interpreted, its implementation could - most Common Lisp implementations feature compilers to binary. The standard even provides you with functions compile and compile-file.
Regarding communities: you've mentioned three (or four) different programming languages. Only SBCL, CLISP and ECL are common lisp implementations and they share the same community - because they implement the same standard. It is as if you had said, that there are separate cython and python communities - each implementation has its merits, but users of both are usually part of the same python community. Similar comparison would be between clang and gcc programmers. Many many Common Lisp systems work well on different implementations of that programming language (some with compatibility layers, some are simply portable programs).
If you need to write a Very Large Lisp program for an industrial application with a lot of moving parts that has to run fast, you probably want Common Lisp.
[0] Racket is now compiled to the metal now too with the recent Chez compiler integration.
Here's a library I trust for linear algebra that uses BLAS and LAPACK. I haven't tried it on Windows.
https://github.com/rigetti/magicl
And of course there's always Maxima, the clone of Macsyma which was the grandfather of Mathematica:
If you're just into functional programming and expressiveness, Clojure blows CL out of the water. Scheme also feels more cohesive, at least R(4,5)RS which is what I know.
The appeal of Common Lisp (to me) are CLOS, the condition/restart system, commercial portable GUI toolkits and specially the low level capabilities. Compared to it, Clojure just feels like a verbose APL.
Depending on the camp you are, Dylan, Factor and Julia are better Lisps than Scheme and Clojure, even if they are not s-expression based.
It's a standard for the main Lisp language with multiple very different implementations, including commercial offerings.
For example at least two quantum computer companies use Common Lisp deep in their stuff.
Currently D-Wave is looking for a Lisp developer for their processor group:
https://jobs.lever.co/dwavesys/eca1f300-d90b-460f-9b7e-2660b...
The main problem I tended to have when starting projects in CL/Scheme was library support. Sure, I could wrap whatever libraries I needed in SWIG or the implementation's FFI, but that was work taken out of my all-too-small pool of time to work on something that wasn't the problem that interested me.
Clojure solves this problem by being hosted while also making a lot of the language changes I once dreamed of making to Scheme and Common Lisp.
CL most cited value: more featured repl, better live debugging