I'm going to use a metaphor for this talk which is drawn from a wonderful book called The Act of Creation by Arthur Koestler. Koestler was a novelist who became a cognitive scientist in his later years. One of the great books he wrote was about what might creativity be.—Learning.—He realized that learning, of course, is an act of creation itself, because something happens in you that wasn't there before. He used a metaphor of thoughts as ants crawling on a plane. In this case it's a pink plane, and there's a lot of things you can do on a pink plane. You can have goals. You can choose directions. You can move along. But you're basically in the pink context. It means that progress, in a fixed context, is almost always a form of optimization, because if you're actually coming up with something new, it wouldn't have been part of the rules or the context for what the pink plane is all about. Creative acts, generally, are ones that don't stay in the same context that they're in. He says, every once in a while, even though you have been taught carefully by parents and by school for many years, you have a blue idea. Maybe when you're taking a shower. Maybe when you're out jogging. Maybe when you're resting in an unguarded moment, suddenly, that thing that you were puzzling about, wondering about, looking at, appears to you in a completely different light, as though it were something else.
https://tinlizzie.org/IA/index.php/Alan_Kay_at_OOPSLA_1997:_...It might surprise the author to learn that there are many people who:
1) Have tried lisp and clojure
2) Liked their elegance and expressiveness
3) Have read through SICP and done most of the exercises
4) Would still choose plain old boring easy-to-read always-second-best Python for 90% of use-cases (and probably Rust for the last 10%) when building a real business in the real world.
The article could really benefit from some steel-manning. Remove the cute Flatland metaphor and it is effectively arguing that lisp/clojure haven’t been universally adopted because most programmers haven’t Seen The Light in some sort of epiphany of parentheses and macros. The truth is more nuanced.
The technical merits of languages just aren't relevant to choosing them for most developers, unless they're helping solve a people problem.
"Artisanal" languages like Lisp, and Forth can be fantastic at solving problems elegantly, but that's not the most important thing to optimize for in big organizations where a large portion of your time is spent reading code written by people you've never met who may not have known what they were doing.
Many of the tools that come from big tech are designed to ease the challenges of organizational scale. Golang enforces uniform styles so that you don't have idiosyncratic teams doing their own things. Bazel is a largely language agnostic build system, with amazing build farm support. Apple and Google have both contributed heavily to sanitizers and standard library hardening in order to detect/eliminate issues without reading the code. Facebook has poured vast resources into automatic static analysis. AWS built an entire organization around treating all their internal interfaces the same as external ones.
I think the field of programming languages has grown enough that we have to start acknowledging the future of programming largely won't be in the context of what it means for devs working at large corporations. One of my favorite talks is from Amy J. Ko called A Human View of Programming [1], which argues there are many other ways to look at programming than "tool for generating business activity" and "mathematical construct", which heretofore have been the dominant views of programming languages.
Because there are so many other forms and purposes programming languages can and will take (she goes through them in the talk), so evaluating them and creating them solely on how well they are able to fit into a corporate R&D pipeline is a very narrow and short-term view of the field.
Indeed, it's been the case for a long time now that most people who write programs are not in fact professional software developers. The most used language in the world is Excel, by several orders of magnitude, and it's the opposite of everything devs say a "proper" language must be. There's something we as a field still need to learn from that.
Is the most used bridge-building technique a plank over a small culvert, or the properly engineered bridge that carries constant, multi-lane highway traffic for a century? How do we weigh the usage of resulting products into the usage of a design and production method? Should we consider the number of program users? The users X hours of usage?
Fundamentally, the software field is still just so young and we haven't teased apart the "obvious" different domains and domain rules that we have for production of different material goods. In some sense, the domains and domain rules for material goods emerge out of the connection to culture, economic roles, health, and safety aspects. Whether it falls into civil engineering, building codes, transporation rules, consumer product safety, food and drug, ...
The self-similar way that software can be composed into systems also makes it confusing to categorize. Imagine if we talked about other crafts the same way, and conflated textile manufacturing, clothing design, tailoring, costume making, wardrobe management, scripting, choreography, acting, and dancing as a single field that coordinates the visual movement of fabric on a stage.
Instead, the world should have seen the light of Hindley-Milner type systems, ML-inspired languages, immutability, or at least not sharing mutable state. Did Haskell fail? Hmm, let's look at Typescript and Rust.
Don't get me wrong, a Lisp is always a great and fun language, and you can write whatever DSL you might like on top of it. But the old joke that "a Lisp programmer knows the value of everything, and the cost of nothing" still has quite a bit of truth to it.
But the real strength of Lisp is in the macros, the metaprogramming system. And I suspect that typing most macros properly would be a bit less trivial than even typing of complex generic types, like lenses. Not typing a macro, and only typechecking the macroexpansion would formally work, but, usability-wise, could be on par with C++ template error reporting.
Spec is definitely underrated here considering it's built into the language and has a wider scope but for most people they want the intellisense experience which you can get with clj-kondo + mailli but is not built in so most teams don't use it, fair enough
I'd like to move the goal posts though and say I want flowstorm in every (any other?!) language
I can just run the program and scrub backwards and forwards through the execution and look at all the immutable values frame by frame with a high level UI with plenty of search/autocomplete options
For program understanding there's nothing better
The fact I can program against the timeline of values of my program and create custom UI on top is crazy
One of the most mind blowing demos to me was Bret Victor's inventing on principle and having a programmable reverse debugger for your language makes those demos viable
I built an emulator recently for work that replays what happens on live locally, combined with flowstorm I can go line by line and tell you exactly what happened and why, no print statements no reruns with my own custom UI customised to our apps interesting parts
This is my appeal to anyone outside of Clojure please build flowstorm for JavaScript and or Python
The design of flowstorm is definitely helped by the fact that 95% of Clojure programs are immutable but I don't think it's impossible to replicate just very difficult
The talk I posted from Alan Kay is the steel man. I think you've missed the essence of TFA because it's not really about Clojure or lisp.
If you only think about programming languages as a way to make money, the analogy of being stuck in Flatland is perfect.
But TFA was riffing on Paul Graham's old essay Beating the Averages, which argued precisely that the expressiveness of Lisp gave his startup a business edge. That was the context of my comment. I'd add that most of what most of us do in our day jobs is to use programming languages to make money, and there's no shame in that at all. And if you want to talk about why certain languages get widespread adoption and others not, you have to talk about the corporate context: there is no way around it.
But I'll rephrase my question, just for you: "what abstract problems can you solve or thoughts can you express in Clojure that you can’t express in Python or Rust?"
I think the money question is a red herring here. I’d phrase it more like: what problem in a user’s problem space is expressible only like this? And if the only user is the programmer, that’s alright, but feels more aligned with pure academia. That’s important, too! But has a much smaller audience than engineering at large.
Programming language ergonomics matter and there is a reason why Lisp has so little adoption even after a half a century.
1) Have tried lisp and clojure
2) Liked their elegance and expressiveness
3) Have read through SICP and done most of the exercises
4) Would still choose plain old boring easy-to-read always-second-best Python for 90% of use-cases (and probably Rust for the last 10%) when building a real business in the real world."
This is me to a T — even when I'm building hobby projects. The point of writing any code, for me, is most of all to see a certain idea to fruition, so I choose what will make me most productive getting where I want to go. And while I still worship at the altar of Common Lisp as an incredibly good language, the language matters much less than the libraries, ecosystem, and documentation for productivity (or even effective DSL style abstraction level!), so eventually I have had to make my peace with Python, TypeScript, and Rust.
An incredible epiphany that you can't transmit may not be as useful as a a moderately clever idea you can.
i think lisp's magic is a lot more cultural than most people think. i.e. how lispnicks implement lisps and the ecosystem around it. how easy it is to walk the entire ladder of abstractions from machine code to project specific DSL's. how pluggable its parsing pipeline is -- something that is not even exposed in most languages, let alone customizable.
the language, the foundation, of course matters. but i think to a lesser extent than what people think. (hence the trend of trying to hire lispnicks to hard, but non-lisp positions?)
and it's not even an obviously good culture... (just how abrasive common lispers are? need to have a thick skin if you ask a stupid question... or that grumpy, pervasive spirit of the lone wolf...?)
maybe it's just a peculiar filter that gets together peculiar people who think and write code in peculiar ways.
maybe it's not the macros, but the patterns in personality traits of the people who end up at lisp?
Using a bad language for 8 hours a day makes me irritable and it's impossible to prevent that irritability from overflowing into my interactions with other people. I'd rather that my conversations with the computer be joyful ones.
Show me. Specifically, material outcomes that I will care about.
There are quite a few programmers who say lisp led to early retirement. That was a pretty interesting idea to me. I like going to the beach a lot.
I am not so sure about people who don’t want to get done: if you like doing what the ticket says instead of the other way around lisp probably isn’t going to be something you’re interested in.
Thing is, other languages do this with metaprogramming or explicit codegen. Everyone needs metaprogramming sometimes—that's why everything supports it, actually.
> In that essay Paul Graham introduced the “blub paradox” as an explanation for this disconnect. It’s a great metaphor I’ve referenced many times over the years. This post is my take on explaining this disconnect from another angle that complements the blub paradox.
The blub paradox, and the author's "flatland" methaphors, function as thought-terminating cliches. They provide the author (and Lisp proponents) with a simple explanation ("Everyone else is stupid") that doesn't force them to reconcile with more difficult questions ("Is it possible that other intelligent people have considered Lisp and rejected it for good reasons?")
And, honestly, it's just an annoying line of reasoning to hear that the only reason <you> don't use <favorite technology> is because you're just not perceptive enough.
For instance, the suggestion that "ecosystem" problems are "misconceptions" that critics fail to reconcile seems inaccurate to me. Does Clojure have a package manager as simple and straightforward as npm/cargo? Does it have a type system as well-maintained as TypeScript? Does it have a UI library as good as (choose your favorite web UI library)? These are all ecosystem problems. Do you think these problems meant nothing to everyone who decided against Clojure? Or do they all live in Flatland?
> The ability to manipulate compile-time so effortlessly is a new dimension of programming. This new dimension enables you to write fundamentally better code that you’ll never be able to achieve in a lower dimension.
There are many such "new dimensions of programming". Macros are cool, don't get me wrong. But given the choice between a proper macro system or a proper type system, I know which one I'm choosing every time.
There are plenty of reasons it might be better not to use Lisp, but very few people actually get as far as considering them.
> The programmers who live in Flatland
> Likewise, you cannot comprehend a new programming dimension because you don’t know how to think in that dimension
> the sphere is unable to get the square to comprehend what “up” and “down” mean.
All of this is patronizing. It implies that I am incapable of understanding the benefits of Lisp. If only I were able to lift myself out of the dull swamp I find myself in! But I am capable, and I do understand them, and I still don't like it! And I think most Lisp detractors do as well! I would argue that it is the Lisp proponents that live in Flatland - they need to understand that there's another dimension to criticisms of Lisp that aren't just "I don't like parentheses" and that there is substantive feedback to be gleaned.
The irony is Clojure(script) has all those things. By virtue of being hosted on the JVM and Javacript and having first class interop with both. ClojureCLR even gives you access to all of C# etc.
Being hosted was a great play in terms of ecosystem.
What it doesn't have is ALGOL style syntax.
That is a big assumption about the way popularity contests work.
That said, like in anything else, this kind of craftsmanship doesn't translate to monetization and scale the markets demands. What markets want is to lower barrier for entry, templatize, cheapen things, and so on.
It's normal then that languages optimized for the lowest common denominator, with less expressive power and more hand holding have won in popularity in enterprise and such, where making money is the goal, but that Lisp remains a strong and popular language for the enthousiasts looking to level up their craft or just geek out.
This is a profound misapprehension of the nature of language design. Languages exist within contexts, and embody tradeoffs. It is possible- common, even- to fully grasp the capabilities of a language like lisp and still find it inappropriate or undesirable for a given task. Pick any given context- safety-critical medical applications, constrained programming for microcontrollers or GPUs, livecoding environments where saving keystrokes is king- and you can find specialized languages with novel tools, execution models, and affordances. Perhaps it never crossed Paul Graham's mind that lisp itself might be a "blub" to others, in other situations.
The idea of a linear hierarchy in languages is the true flatlander mindset.
You’re even sort of making the same point. Specialized problems need specialized tools. How do you write those specialized tools? Start from scratch, or just make a Lisp package?
Instead, it's just an ad-hominem attack based on the idea that non-Lisp programmers are too limited in their thinking to appreciate Lisp.
Show me a convincing example of something that's simple/clear/elegant/superior in Lisp, and how difficult/complicated/ugly/impossible it would be to do the same thing in Java/C++/Ruby/Python.
In the absence of that, the entire article can be refuted by quoting The Big Lebowski: "Yeah, well, you know, that's just, like, your opinion, man."
You can also read anybody ranting about how great Zig comptime is if you want more contemporary examples.
If someone writes code based on an algorithm out of a 1985 textbook, and I tell them that they could make it go 20X faster if they learned more about processor architecture (out-of-order execution, cache coherency, NUMA, etc.) — a new dimension of programming to them — am I making an ad hominem attack?
Once I made somebody’s SQL query 100X faster by explaining what an index was. Fortunately they didn’t think I was attacking their intelligence.
Serialize and deserialize data. You're currently using something like XML or JSON for a human readable data serialization format in those languages. JSON and XML are not first class components of those languages. S-expressions are a better version of JSON and are first class components of Lisp.
(but you often get something much better when config files are plain lisp code; i.e. they are eval'ed, assuming that the threat model allows it)
I think it's just trying to say there's another dimension, the meta-level enabled by macros and Lisp's syntax that opens up the possibility of new solutions, which may or may not be better, as that's so context dependent.
But what I feel it's saying is you can't even begin to imagine solutions that leverage this new dimension without learning about it and getting to grip with it mentally.
In that sense, it's saying when you don't know, you can't even explore the space of solutions at that higher dimension, not necessarily that they're better for all problems.
100% this. I think you can replace "languages" in that sentence with many things (employee levels is another big one that is relevant to this forum - employee value comes in many, many shapes). Reducing complicated things to one dimension can be a useful shortcut in a pinch, but it's rarely the best way to make complicated choices among things.
Maybe I still haven't had my epiphany, but I'm not a huge fan of macros in lisps and DSLs (like what ruby is known for). It makes code harder to understand.
> Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
Lisps are a continuum, and I still think there's room for new ones that are even better.
The only thing AST-level macros help with is creating custom syntax to cut down on boilerplate. That's very cool, but it comes with a cost: now you have to learn new syntax.
I love Lisp. I've written tiny Lisp interpreters for most of my games (Chron X, Transcendence) and even GridWhale started out with a Lisp-like language.
In my experience, Lisp is great when you have a single programmer who understands and controls the whole source tree. Once a program exceeds the capacity of a single programmer, more conventional languages work better.
Why is println! a macro when it's a function in almost all other languages?
Rust doesn’t need that, it’s mostly Rust code in the standard library, with only a small bit of compiler magic triggered by the macro. (Println! isn’t the best example because it does have that small bit of magic; most macros are just plain Rust code.)
Here’s a very impressive set of macros that I use daily. [0] This lets you do “printf logging” on an embedded device, with the human readable strings automatically pulled out into a separate section of the ELF file so the actual log stream data is tiny.
I did a similar thing for C a while ago, as a pre- and post- build step. It worked, but much less well, and was a maintenance nightmare.
Edit: and yeah, I think you do need to know you’re calling a macro, because macros aren’t limited to “normal” syntax or semantics. The ! is a signal that you’re escaping the usual bounds of the language. Like this. [1]
[0] https://defmt.ferrous-systems.com/macros
[1] https://docs.embassy.dev/embassy-stm32/git/stm32f301k6/macro...
But I don't get this "Lisp is so much better than everything else," thing. It feels very jejune to me.
Most lisp programmers barely use macros and most programming languages these days have most of the features of Lisp that originally made it useful (automatic memory management, repls, dynamic typing*, and even meta-programming if you really want it).
I do think that most common languages are mediocre but mediocrity is just how humans are.
--
If I had one thing I want fixed about Scheme it would be the dynamic typing, especially since many Schemes compile aggressively. Finding bugs is much harder when your apparently dynamic language has compiled out everything useful for understanding an error condition. Most of those mistakes could be caught at compile time.
Also, consider that good work - particularly in art but also in engineering - requires constraints. Knowing what you cannot do adds guard rails and a base set of axioms around which you can build. Perhaps the power of LISP macros and AST manipulation is not “powerful and thus good”, but rather “too powerful and thus complicated”. Needing to write out a boring old function/class/module instead might leave you with code that is simpler to read and design around.
"Lisp/Clojure macros derive from the uniformity of the language to enable composing the language back on itself. Logic can be run at compile-time no differently than at runtime using all the same functions and techniques. The syntax tree of the language can be manipulated and transformed at will, enabling control over the semantics of code itself. "
If you are a smaller consultancy solving hard problems, then you might need this.
The problem sometimes is: "I don't want this level of complication, especially when I am going to hand it off to other people to maintain it."
In the business world, you are not gated by your intelligence, but by the average IQ of the people who are going to maintain it over the years.
I've never seen a general purpose programming language that couldn't do everything the underlying hardware is capable of. It could only be unperformant enough that you could call it unfeasible at worst. What's so hard to do in languages other than Lisp? Spam parentheses?
Nobody thinks natively in nested prefix notation.
parpfish•7h ago
because, i guarantee that it's not beyond our comprehension. at some point the author was a 2d-er that read/did something and had their understanding expanded. so... do that for us
1313ed01•6h ago
joeevans1000•6h ago
nathan_compton•4h ago
Sophira•6h ago
I had heard before that Lisp had something called "macros", but I didn't know exactly what they were or how they differed from C macros. This blog post kind of explains that, but not in a way that couldn't also apply to C macros if you tried hard enough.
I want to know more, but I didn't have any examples here to look at. I may look them up now that I have an idea.
joeevans1000•6h ago
https://blog.redplanetlabs.com/2025/04/22/how-gd-netcetera-u...
joeevans1000•6h ago
"You can get in touch with us at consult@redplanetlabs.com to schedule a free consultation to talk about your application and/or pair program on it. Rama is free for production clusters for up to two nodes and can be downloaded at this page."
somethingsome•1h ago
I remember playing with call with cc, or creating a flow programming language, thinking in higher order, etc..
I clearly do not want to work with lisp, and many of those concepts can be used in other languages without too much effort now (lambdas, map, filter, reduce,... Among the most common and useful).
I think learning lisp is nice as it helps explore interesting areas of programming on a mental level. I can't stress enough how it can wrap your mind sometimes.
Will it help you program faster and bug free? Probably not, will it improve your mental model of programming languages, probably. Will you enjoy learning abstract things, if you like solving math puzzles, probably, otherwise probably not.
It's hard to express the 'powers' it gives you, it's like spending much time thinking about simple things that usually you just use without thinking about.
As a crude example, the scope of a variable shared between two lambda function that is not shared with the global space.
Sorry that I don't have a specific example in mind, I feel like the 'power' is just spending enough time thinking on complex things.