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.
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.
Show me. Specifically, material outcomes that I will care about.
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?
In the anti-macro camp, they’re hard to write, reason about, and debug stack traces. They are also tempting to use when you shouldn’t, and I think a lot of software shops would run into trouble with them.
Regarding Clojure, I wouldn’t call Clojure a write-only language, but I did find that my Clojure code was more inscrutable than my code in other languages— roughly as inscrutable as my Haskell code. Something about it makes me want to code-golf my way into tiny little clever solutions.
Also, I’ve been burnt by various pitfalls of dynamically typed languages— upgrading dependencies in large dynamically typed projects, etc. I’ll take static types over macros any time.
Also, Clojure’s start up time was off-putting, and would probably be even more so today, coming from Bun and Go.
These days, most of my work is in TypeScript, and it’s just fine. Not perfect, but fine. I haven’t missed macros much.
All that said, I do like Clojure. I miss the baked in immutability, the ability to omit commas in arrays / lists / maps / etc, keywords, and the threading macros.
In summary, some of us have given it a shot, and ended up choosing a different path, and that’s ok.
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.
"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.
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.
Macros are preferable to runtime reflection and monkey patching, but the compile-time reflection and monkey-patching represented by macros still incurs a complexity tax that needs to be weighed against the alternative of non-macro code.
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.
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:_...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?
> 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.
Consider e.g. the "with" statement in Python[1]. Someone came up with the idea, found a way to integrate it into python and a year later, people could use it. In Lisp, you write a macro.
Now Python is a rather agile language as these things go. In other languages it would be a lot more than a year. When I was in college, my professor wanted us to use generics, but the school mandated language, Java, lacked generics at the time. So we were told to use a fork of javac that had generics added. Pretty much none of the development tools would play nicely with this, and javac was at least two orders of magnitude slower at compiling than my preferred java compiler at the time (jikes).
None of this is world-ending, but it really is annoying. The argument for macros is just "what is the next generics/with/whatever feature that your language is missing." Most of the features that lisp programmers use macros for have made it into modern languages that continue to evolve, so the leverage narrows. In the late '90s it was probably a much bigger multiplier than today.
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
Just like today's UX designers who need a 3D surface to draw a lousy rectangle.
https://blog.redplanetlabs.com/2025/06/17/make-worse-softwar...
Nobody thinks natively in nested prefix notation.