Rendered at 18:28:45 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
heisig 1 days ago [-]
The main novelty here is that the author just made the entire book available to the public for free.
I have previously read the printed version, so maybe now is a time for a very brief review. The book is technically fascinating and a worthwhile read, but it is also highly opinionated even by Lisp standards. Then again, it is refreshing in this time and age to see this deeply human and creative side of programming. I wholeheartedly recommend others to read it - and to carefully choose which of the advice to follow and which not :)
Thank you so much, Doug Hoyte, for making this book available to all of us!
gjvc 1 days ago [-]
so the date in the title is wrong
rootnod3 16 hours ago [-]
No, book was published 2008.
gjvc 3 hours ago [-]
yeah, no shit. i have a copy. if you care to read the actual link it's about an update this month, october 2026.
mark_l_watson 1 days ago [-]
I bought and read Doug’s book years ago, glad to see it surfaced here with the announcement that a PDF and HTML version is available.
I have been programming in Common Lisp since the early 1980s, love the language, but I just use the language simply. That said I like the things that Doug, Paul Graham and others write about great Common Lisp techniques.
noiv 22 hours ago [-]
Has anybody experience with LLMs and Lisp? I'd assume they love the uniform syntax and may even spend less tokens. But is there enough code to train?
iLemming 17 hours ago [-]
Yes. Lisps are great (probably the best) when paired with LLMs. Clojure is well-known to be one of the most token-efficient [mainstream] languages, due to the mere compactness of its syntax. The syntax density can be easily observed by grabbing a piece of JSON and converting it to idiomatic EDN; it would be almost twice as compact and far more readable.
When an LLM is given access to a REPL, it gets even more interesting. Agents stop guessing and start empirically analyzing the current state of affairs, changing things dynamically, reaching the correct solution much faster and costing even fewer tokens.
Quitschquat 1 days ago [-]
This and On Lisp were mind blowing for me at the time.
The book is wonderful to read and get your mind blown by all the ingenious, clever, and surprising things that are possible using basic building blocks of Common Lisp - so that you know exactly what code you should NOT be writing when doing Lisp for anything serious and involving other programmers.
It's very good for realizing the difference between what is possible and what is feasible, since Lisp mastery requires both knowledge of what is possible to do and restraint in the actual use of those possibilities. Clever things require cleverer debugging techniques, and Let Over Lambda is absolutely full of the former.
6gvONxR4sf7o 1 days ago [-]
I've always wished there was some language with deeper IDE/LSP integration for macros. It's hard to connect the tokens a developer types to the language and to behavior in their programs, but a huge amount of that plumbing can be done at the language/macro system, and the rest can be made wildly easier. And yet every language and IDE I know really drops the quality of life on macros.
Yeah, its pervasive use of explicitly, deliberately nonhygienic macros was surprising when I first read it. Interesting to consider and also good to understand why it'd be a nightmare to debug code written that way.
gumby 14 hours ago [-]
Hygienic macros did not exist when CL was being standardized. They were invented by the scheme community.
phoe-krk 4 minutes ago [-]
IIUC "hygienic" in this context relates not to the define-syntax style of macro writing that eliminates even a chance to leak symbols, but to the deliberate choice where plenty of LOL macros introduce implicit bindings as a part of their functionality.
It's possible to write macros without problems like variable capture in Lisp, it just takes some more care and a choice to follow this paradigm. LOL macros often explicitly choose not to follow it.
mike_ivanov 1 days ago [-]
There is plumbing code and there is porcelain code. There is nothing wrong with being clever in the plumbing area, even with other people peeking under the hood. The porcelain side is more nuanced though - it takes a special kind of cleverness to deliver intent with clarity.
A personal anecdote - not long ago I saw a beautiful piece of code (not mine) using the Result monad being rewritten as a chain of nested if statements - all because it was "too clever to understand". Go figure.
phoe-krk 1 days ago [-]
> There is nothing wrong with being clever in the plumbing area, even with other people peeking under the hood.
Sure, with proper documentation and comments and enough modularity to refactor this code as necessary - your example of moving between Result and an if-chain is an example of this.
antonvs 1 days ago [-]
The Result example illustrates this debate nicely. Software is composed entirely of abstractions, even down to the machine code level. You have to understand the abstractions to use them effectively.
"Too clever" is subjective, and often just means that the developer lacks sufficient familiarity with the abstractions, such as Result in this case.
The abstractions are what allow us to build systems with intrinsic complexity and keep them manageable. The "too clever" accusation is about perceived complexity, and depends on the observer. Expertise changes what seems complex or simple to someone.
frou_dh 1 days ago [-]
Looks like the well known book has just become free (online or PDF)
shawn_w 20 hours ago [-]
Doug Hoyte is a man of very strong opinions (most of which are wrong), which makes this book more annoying to read than it could have been.
1 days ago [-]
js8 1 days ago [-]
I read the book years ago, and while I think it's interesting, today I think it's better to learn lambda calculus directly, without the Lisp "gimmick".
iLemming 16 hours ago [-]
"[It's better to] learn type theory, category theory, lambda calculus, logic, etc." I have heard a similar notion for years. And I tried. Oh boy, I tried. Grokking Haskell felt like a Sisyphean grind. And then I tried Lisp. I dunno what happened to my brain, but the sheer pragmatism and plain simplicity of it suddenly made all the things that before felt so difficult to grok clearer than Lego-set instructions. Recursion, with its small intricacies that confused me for years, made me realize how simple it actually was, I just wasn't seeing it the way it actually is. Y Combinators, Folds, Monads, Applicatives, Laziness, and many other things.
I wish I had found Lisp many years sooner. That simplified Haskell, Rust and Idris for me. The downside is that it turned out to be vastly pragmatic, and for personal stuff I'm on Lisp. Even though most things at work are not.
So, maybe you should honestly self-reflect: had that book not happened in your life before, would you even consider understanding LC today, unadulterated by "gimmicks"?
js8 8 hours ago [-]
I think you're making a good point, perhaps it was necessary in my path (which was roughly C++ -> Python -> Common Lisp -> Forth -> Haskell -> soon Lean).
But perhaps we're teaching lambda calculus wrong. Let and lambda are essential building blocks of it, and Lisp is a sort of special case.
I don't think it has to be hard - To Mock a Mockingbird is just as enjoyable as LoL. It's just difficult to see significance of LC for programming, I think, because people do not think of lambda calculi as programming languages.
Jtsummers 1 days ago [-]
> I think it's better to learn lambda calculus directly, without the Lisp "gimmick".
The book isn't about teaching lambda calculus, though. It's covering things you can do in Common Lisp, specifically around macros.
lanstin 1 days ago [-]
And around lexical binding with functions as first class values. That to me is the lesson that is possible in other non-CL environments. E.g. JavaScript.
I have previously read the printed version, so maybe now is a time for a very brief review. The book is technically fascinating and a worthwhile read, but it is also highly opinionated even by Lisp standards. Then again, it is refreshing in this time and age to see this deeply human and creative side of programming. I wholeheartedly recommend others to read it - and to carefully choose which of the advice to follow and which not :)
Thank you so much, Doug Hoyte, for making this book available to all of us!
I have been programming in Common Lisp since the early 1980s, love the language, but I just use the language simply. That said I like the things that Doug, Paul Graham and others write about great Common Lisp techniques.
When an LLM is given access to a REPL, it gets even more interesting. Agents stop guessing and start empirically analyzing the current state of affairs, changing things dynamically, reaching the correct solution much faster and costing even fewer tokens.
Checkout the Forth implementation in https://letoverlambda.com/index.cl/guest/chap8.html
It's very good for realizing the difference between what is possible and what is feasible, since Lisp mastery requires both knowledge of what is possible to do and restraint in the actual use of those possibilities. Clever things require cleverer debugging techniques, and Let Over Lambda is absolutely full of the former.
It's possible to write macros without problems like variable capture in Lisp, it just takes some more care and a choice to follow this paradigm. LOL macros often explicitly choose not to follow it.
A personal anecdote - not long ago I saw a beautiful piece of code (not mine) using the Result monad being rewritten as a chain of nested if statements - all because it was "too clever to understand". Go figure.
Sure, with proper documentation and comments and enough modularity to refactor this code as necessary - your example of moving between Result and an if-chain is an example of this.
"Too clever" is subjective, and often just means that the developer lacks sufficient familiarity with the abstractions, such as Result in this case.
The abstractions are what allow us to build systems with intrinsic complexity and keep them manageable. The "too clever" accusation is about perceived complexity, and depends on the observer. Expertise changes what seems complex or simple to someone.
I wish I had found Lisp many years sooner. That simplified Haskell, Rust and Idris for me. The downside is that it turned out to be vastly pragmatic, and for personal stuff I'm on Lisp. Even though most things at work are not.
So, maybe you should honestly self-reflect: had that book not happened in your life before, would you even consider understanding LC today, unadulterated by "gimmicks"?
But perhaps we're teaching lambda calculus wrong. Let and lambda are essential building blocks of it, and Lisp is a sort of special case.
I don't think it has to be hard - To Mock a Mockingbird is just as enjoyable as LoL. It's just difficult to see significance of LC for programming, I think, because people do not think of lambda calculi as programming languages.
The book isn't about teaching lambda calculus, though. It's covering things you can do in Common Lisp, specifically around macros.