Freeing Your Goats
And Apologizing For Bad, Ineffective Writing
A little while ago, a post I thought almost nobody would read made a tour of the top slots on some popular aggregators: it was #4 on Hacker News, on the front page of Lobsters, and attracted some attention on Reddit.
First, Sorry To Have Gotten Your Goats
While a few people reached out to say how much they liked the post, the commentary was mostly negative. Friends, this was not what I wanted. I'm not a great writer (not of comedy anyway) and the rhetorical approach I had taken, which I intended be whimsical and goofy, flat-out failed. Really, truly sorry to have gotten your collective goats. I hope they remain in good health as I try to get them back to you.
One commentator, for example, observed that the word "totalitarian" is silly when applied to programming languages. I agree completely, it is silly. I hoped to be silly but, it seems, I was a little lazy. I used an inconsistent tone which ruined the whimsical effect I was going for, and it wasn't clear what the tone was actually meant to be. Sorry about that.
I had expected the post to be read almost exclusively by lone neophytes cruising the Internet late at night in search of recent Common Lisp propaganda to keep their spirits up. My aim was to partially fill a void that I had waded out into a few years back when, after a 10+ year hiatus from Common Lisp, I re-entered its odd corner of the software world.
I Love Both Rust and Haskell
This didn't come across for most readers, but I have used both Rust and Haskell, and I enjoy them both immensely. I've even been paid to develop in Haskell, even situations where I had authority to pick the language and tech stack for the project. That's how much I like the language and ecosystem.
And though none of my professional work has involved Rust, I have used it to make several small tools and the experience has been entirely pleasurable. I did not struggle with the borrow checker. I enjoy the sugar that makes returning types isomorphic to
Maybe t and
Either s t easy to do. I agree with its decisions about memory safety. I felt genuine awe when I was able to cleanly express a safe concurrent shared memory access pattern in a single tidy type alias. It's f**king incredible!
When Rust hit 1.0 I kind of thought: geeze, do I even need Haskell anymore? Who needs STM when there's
And, about static vs dynamic typing - I'm a huge fan of Haxe. Haxe is a mature, statically typed language with an expressive type system and advanced compiler (a transpiler really). It's as close to write once run anywhere that I've come across for games and other interactive applications. In any case, static typing is not my enemy.
An Aside on my Rust vs Haskell tension
I decided that I still like thinking in Haskell better, even if I prefer producing software in Rust. Even now, when I'm spending my "free time" writing Common Lisp, I often think in terms of Haskell: types, function composition , and monads. Quick Tip: you can mostly simulate certain monads, including State and Reader, with special variables in Common Lisp.
I Agree With Most Of The Critiques
It seems to me that some of the most relevant critiques were about sociality and teamwork - that Rust and Haskell (and in my opinion, especially Rust) promote pro-social things like:
- easy refactoring
- easy(ish) perusal of and grappling with other people's code
- that the compiler gives confidence to even "junior" devs when diving into complex problems.
I completely agree with this perspective, and in a way, it is compatible with what I was trying to highlight about Common Lisp.
Many of you got this point across in your comments: Common Lisp is very good (or bad, depending on your perspective) at letting individuals get weird. Obviously, individuals getting weird is not always conducive to the product life cycle at software shops both large and small. I agree.
But sometimes... I want to get weird. Moreover, I dream of one day working with a small weird team, each of whom is difficult to replace. Business sense be damned.
What I Really Wanted To Say
Common Lisp offers me a compelling and engrossing approach to working on software. Smalltalk is similar in this regard, and in some ways superior.
It isn't about the REPL. In fact I'm barely ever in the REPL. Instead, I'm literally looking at my running program while I navigate through the source code in my editor. From this perch, I can recompile individual functions by placing my cursor somewhere inside the function body and typing
Control-c Control-c, which then immediately updates the program as it is running.
When I am working this way my program never crashes, and therefore never loses state, not until I tell it to. If I introduced a bug in the function I just recompiled, and if that function is called in a tight loop, the program will enter a debugger instead of unwinding the stack. I can look at the function, at some of the objects it operated on, fix it, recompile, and "return to previously scheduled programming", so to speak.
This approach is really fantastic for working on interactive media like games, but also for things like web apps. Anything with a GUI.
Think about it like this: You're making a game. In the game you know that a certain item should appear when you enter a particular room deep within the game's level. You navigate to the level but the item isn't there. In C++ you'd do something like: close the game window, go to the source, think about the problem, make a change, recompile, start the game again, navigating back to the room, which may be deep within the level, and check whether or not you fixed it.
But with Common Lisp you just recompile the function while you are looking at your avatar as it stands in the room. No need to shut the game down first, no need to walk back to the room.
Thanks for reading