Why I still reach for Lisp and Scheme instead of Haskell

The author explores the tension between mathematical purity in Haskell and the pragmatic flexibility of Lisp and Scheme, explaining why the latter remains the 'sweet spot' for rapid prototyping and productivity.
There is a persistent tension in software engineering between the beautiful, mathematically pure ideal of a program, and the messy, pragmatic reality of just getting things done. Over my career, I’ve explored the depths of both extremes in an attempt to find my personal sweet spot for hacking.
Before you sharpen your keyboards and start a flame war over the title, let me point out that I haven’t written this post to talk bad about Haskell, or any other tool for that matter. In fact, I love Haskell. I taught myself, banged my head against the wall over the course of three years, and built several real-world projects with it (some even became a bit lucrative).
Between my time in the web development world, the Go world, the JVM world with Java, Scala and Kotlin, and my long history hacking in Lisp (Emacs, Common, Scheme), I have come to deeply appreciate functional programming.
Enlightening as it can be
Haskell has what likely is the most amazing, enlightening and complex type system to work with (as do more ML languages).
It is also the undisputed king of introducing mathematical ideas and concepts to programming, and popularizing them. Haskell circles are frequented by PhDs, computer science researchers, category theorists and all kinds of smart people.
Some of the amazing innovations of Haskell or that it has helped popularize, which blew my mind several times:
- algebraic data types
- pattern matching
- functors, monads
- monoids, semigroups
- effectful computation modelled as monads
- purely functional domain-specific languages (DSLs)
All these kind of things often feel bolted-on or missing entirely in other languages! For all its brilliance, Haskell resists most of the attempts people make to just hack and write useful code quickly.
When pragmatism enables actual productivity
Scheme (and Lisp in general) might lack Haskell’s innovations and purity, favoring a minimalistic flexibility instead, but it mixes practicality with functional beauty in a way that makes it a functional language for human beings.
Actually, in my opinion, Scheme (and Lisp) allows you to express complex systems and problem domains in more simple terms than any other language can. Take a recent adventure of mine, for example. I was spinning up a prototype for a bookmark management tool.
I started in Haskell as I thought the beauty of data modelling and pure side-effect-free reasoning would work well. One of the steps in the proof-of-concept was transforming some data models to XML and output them to a file. If I were doing this in Kotlin or Java, it would be trivial. After a frustrating hour with my Haskell project, I was still wrestling with the dependencies and monadic API, and I ended up giving up on the whole thing.
This has often been my friction point with Haskell. It is beautiful, but it fights you when you just want to get your hands dirty and prototype, without a big design upfront. Scheme (GNU Guile for me) doesn’t have Haskell’s brutally efficient compiler, but it has the terseness, power, and more importantly, it makes the actual act of hacking a joy.
As a long-time Lisper, for me this is a massive barrier to usability. Scheme happily sacrifices academic purity so you can slap a (write ...) anywhere in your code and instantly see what’s going on. The friction added to quick-and-dirty debugging in Haskell is a tax I am simply not willing to pay when I’m trying to move fast.
Meta-programming and DSLs
The second problem with Monads is directly tied to their greatest strength: they are synonymous with Domain Specific Languages (DSLs). The promise of DSLs is fantastic, but the success of Parsec has filled Hackage with hundreds of bespoke DSLs for everything. Each demands its own learning curve and often lacks syntax consistency.
As we Schemers know, Scheme is intentionally simple. That simplicity isn’t a limitation; it’s what makes it endlessly flexible. While modern JVM languages rely heavily on reflection or complex compiler plugins to achieve this, Lisp hackers have been effortlessly reshaping the language for decades using the powerful macro system.
I’ve used Scheme for countless projects because of its combination of features and philosophies that bring it to my personal “sweet spot”. When you want to mold the syntax directly to your will, Scheme gets out of your way and helps you achieve it.
Source: Hacker News















