Why I still reach for Lisp and Scheme instead of Haskell
Lisp/Scheme vs Haskell: overall sentiment
- Many commenters agree with preferring Scheme/Lisp for personal projects because it “fits how they think,” especially for exploratory or interactive work.
- Others enjoy Haskell but relegate it to niche uses (e.g., window manager configs) or specific domains.
- Some say language choice is mostly about “how you like to work,” not pure technical superiority.
Syntax, expressiveness, and aesthetics
- Lisp’s uniform syntax and small set of “atoms” are praised for composability and conceptual simplicity.
- Several argue Haskell syntax is dense, ambiguous “word salad” that slows reading; others strongly defend it as elegant, concise “executable math.”
- There is extended debate over Haskell’s indentation rules and layout, especially
let/inalignment, with some finding them confusing and others considering them simple or too lenient. - Factorial examples are used to argue that ML/Haskell can be as concise as, or more concise than, Scheme; others say discomfort with unfamiliar syntax is more about taste than ability.
Types, safety, and scale
- A Schemer who built a large Gambit codebase came away wanting a static type system for catching bugs.
- Alternatives suggested: Common Lisp’s optional typing, and multiple “typed Lisps” (Coalton, Carp, Crunch, Jank).
- Some are wary of large Haskell codebases despite the type safety, suggesting tradeoffs between safety and complexity.
Macros, DSLs, and s-expressions
- Opinions diverge on macros: some rarely need them in Racket due to rich libraries; others use them mainly for fun or to remove boilerplate.
syntax-rulesis seen by some as too constrained; others note it was meant as a minimal common denominator, with more powerful systems likesyntax-caseor implementation-specific macro systems.- One thread contrasts Haskell’s Parsec-driven DSL proliferation with the Lisp approach of normalizing XML/JSON into s-expressions, then operating on them uniformly.
- Kernel’s fexpr-based “operatives” are presented as an alternative to macros, blurring compile-time vs run-time and enabling multi-stage programming.
REPL, live systems, and debugging
- Interactive development (REPL, SWANK/SLIME-style) is widely seen as a major Lisp advantage: edit running programs, inspect state, redefine functions, even in production.
- This is reported in Common Lisp, Clojure (via nREPL/CIDER/Calva), and to some extent Scheme/Racket, though Racket’s story is described as less clear or weaker.
- Several note similar but less integrated experiences in Python (
pdb), Ruby consoles, Emacs Lisp, and Java with strong IDEs and tools like JRebel/DCEVM. - Hot-patching in production is described as powerful but risky and rarely appropriate in multi-instance, autoscaled, or security-sensitive systems.
Debugging, logging, and Haskell specifics
- Haskell’s IO and purity make ad-hoc
printdebugging harder; commenters mentionDebug.Trace.traceas a workaround but note laziness affects when prints run. - Some argue they rely less on prints due to small pure functions, property-based testing, and strong types; others note that in distributed systems, robust logging is still essential.
- There is debate over whether Haskell’s constraints and abstractions help or hinder rapid prototyping and “caveman debugging.”
Other paradigms and languages
- Prolog (and Erlang by extension) is cited as better than Lisps for expressing complex domains in relational terms; others say it depends on problem shape and layer Prolog, OCaml, CLOS, and Lisp together.
- Some emphasize that language readability can be assessed with ideas from typography and cognitive load, but what counts as “beautiful” or “natural” remains highly subjective across commenters.