If you buy into the argument that less code, that writing code at a higher level of abstraction results in less time to market, less maintenance overhead, more responsiveness to change in future, less bugs etc. Etc. If you believe a 1000 line program is worse than a readable 100 line program that both do the same thing, then lisp with its macros is that thing.
Super expressive and readable. I went from not being able to read clojure to now having written a few apps in it and feeling comfortable with the syntax in a few weeks.
I definitely write less code to achieve the same ends but it’s still early days for my lisp adventure.
The argument isn't whether less, readable, higher-abstraction code is better than its opposite, it is. It's whether or not a real-world LISP code-base espouses these qualities.
Which I don't believe it does, IMO the primary reason LISP isn't mainstream is because it results in less readable code for humans (i.e. the primary objective of programming languages), it's semantically the perfect minimalist language for a machine but I don't believe it's optimal readability for humans. Other disadvantages include lack of typing & poor tooling support. There's certainly domains it excels at due to its intrinsic qualities but I don't see it ever becoming a popular mainstream general purpose programming language.
First rule of macros is: do not write macros. At least in clojure, it's rare that I stumble upon macros in the wild. But when they're needed (someone else wrote about core.async in this thread) they are very useful.
After one year of clojure, it's annoying for me to read classic C-like languages. There's also people who prefer reading code without syntax color, so clearly this is a subjective matter.
I find clojure tooling really good, and it's hard to go back to a non-repl oriented workflow (this is not at all the same as something like python or javascript repl). But this is admittedly a gray area, there's areas where it's immature compared to other languages, and others where it shines because of it's repl-oriented nature.
The lack of typing is certainly a sound argument, although my personal opinion is that for many use cases it isn't required. This is going to be a contentious opinion, I'm sure.
Note that clojure has an advantage on this over other dynamic languages: idiomatic clojure code means that pretty much everything is pure data, in basic structures: maps and vectors. So the functions that you use to operate on your data are always the same. Over time you'll learn them, and they won't change between domains nearly as much as, say, if you were coding in OOP oriented python.
I've also spent a bit of time with LISPs, when learning Clojure I ported the Clojure 101 LINQ Examples [1] and did appreciate a lot of niceties that Clojure brings with it where the additional syntax actually added to its readability, e.g. the usage of vector syntax for function params provided a welcomed visual separator from its implementation body. Basically all its additional syntax improves readability over a LISP's typical clumped sea of parens where you can more quickly discern different constructs from a glance which would otherwise take me a lot more time & effort trying to determine the boundaries of each expression whilst evaluating them in my head, effectively conveying that the minimal s-expression syntax that's optimal for the compiler isn't optimal for humans.
So when it came time to implementing a .NET LISP [2], I adopted much of Clojure's additional syntax for improved readability & interop with .NET APIs [3]. But you can only improve LISP's syntax so far, e.g. its Template libraries for HTML generation [4] make for horrible HTML DSL's which looks nothing like the HTML it's supposed to generate. The solution to overcome this was basically to not to use LISP for templates, instead create a multi-language scripting language [5] that embeds lisp into it allowing it to Combine strength's of all languages [6], e.g. use LISP for algorithms and Handlebars / JS Expressions for templating.
The REPL is definitely one of its super powers which is one areas where it shines & basically the primary use-case where I still use it. I've created a live "watch" mode & deep integration with .NET libs that I use for discovery, e.g. run DB queries, call HTTP APIs, execute shell scripts, etc. [7]. It especially shines for being able to open a REPL session with a remote production .NET instance letting me inspect its live running state & invoke system functionality like querying its configured RDBMS, executing redis commands, send tweets, emails, etc [8], I've even got it to Live Script Unity objects in-game :) [9], which speaks to the power & elegance of LISP that's able to achieve so much with so little code.
At the same time I don't think REPL-based programming is all that useful during normal development, you can execute encapsulated code fragments fine, but most of the time I'll need my whole environment constructed before being able to inspect it as I would when debugging, so I find it useful for opening a REPL session into a live running instance, but not using the REPL to construct the live instance. So for my dev workflow, static analysis & typing, great IDE, tooling + debugging is a lot more useful.
>IMO the primary reason LISP isn't mainstream is because it results in less readable code for humans
I disagree. Being a mathematician LISP just feels natural and the ugliest, most horrible and hard to read language by far is java (IMO, of course). But that's just probably because all my life I've been thinking about functions and not objects.
If your background is OOP and look at some LISP there's no surprise if it looks unreadable, even more so if you have no real motivation to understand it.
What is or isn't readable can be judged by two qualities. The first one is if it's being familiar to what you're used to and the second one how long it takes to learn if you're not familiar with it.
Now I learned C-like language before I learned Lisp-like languages, so that might be the reason I felt I understood Lisp way faster than I felt I understand C-like languages. There is simply less to learn about the language and more to learn about conventions, while C-like languages always have bunch of extra syntax you have to learn, otherwise the compiler cries.
> Other disadvantages include lack of typing & poor tooling support
Not sure these are inherent to Lisps. There are plenty of typed lisps, and even the ones that don't have types, can have types added to them after the fact, just because they are Lisps.
Regarding tooling, I'd say that the entire C-like ecosystem is far behind any Lisp language regarding tooling. I mainly see people using "println"'s for debugging, and sometimes using a "line debugger", while Lisp developers modify their code at runtime and have a far more advanced debugger, something C-like languages will probably never do as well as Lisp-like languages does it, again because of s-expressions and the code they make you write.
> What is or isn't readable can be judged by two qualities. The first one is if it's being familiar to what you're used to and the second one how long it takes to learn if you're not familiar with it.
So your argument is that all code is as easy to read as long as you have done the work to get familiar with it? I hope you understand that it is bullshit. Brainfuck isn't easier to understand than python no matter how much time you spend with brainfuck.
No, that is not my argument. I'm sorry if I didn't explain myself well enough for everyone to understand.
My point is that "readability" is composed by many factors, not just one. What is "readable" to some will not be "readable" by others. It depends.
For someone who knows Fortran, learning a Fortran-like language is easy (like C or JS). For someone who knows Common Lisp, Clojure is easy. But for someone who knows Fortran, Clojure is less familiar, hence the code will, on a glance, look less "readable".
The other factor is if something is "simple" by itself.
Most of this view comes from Rich Hickey, who wrote Clojure. He discusses "readability" or "simplicity" rather, in his talk "Simple Made Easy". If you haven't seen it before, do yourself a favor and watch it: https://www.infoq.com/presentations/Simple-Made-Easy/
He'll explain it much better, and with further points, much better than I ever can.
> Brainfuck isn't easier to understand than python no matter how much time you spend with brainfuck.
I don't disagree with your overall point, but I actually wonder how true that is. If you spent years working in Brainfuck, and had never touched Python, I suspect it would take a bit of effort before Python was as readable to you as Brainfuck.
>> the primary reason LISP isn't mainstream is because it results in less readable code
It’s fresh in my head just how unreadable i found Clojure when browsing source of random projects on github a couple of weeks ago. Its not that penetrable to begin with.
However, that was only a couple of weeks ago, since then i’ve come to really appreciate the simple magic of lisp syntax.
I’ve also been able to put it to practical use rather than just appreciating it - i’ve been spoiled by Calva in VS Code, structural editing that doesn’t just work, it actually flows - i’m no stranger to structural find and replace in Intellij but this is different, this smoothes an impedance mismatch between our thinking and expressing code.
Super expressive and readable. I went from not being able to read clojure to now having written a few apps in it and feeling comfortable with the syntax in a few weeks.
I definitely write less code to achieve the same ends but it’s still early days for my lisp adventure.