Why I still reach for Lisp and Scheme instead of Haskell
Advocates of Lisp and Scheme argue that these languages make it easier to prototype and evolve complex systems, thanks to simple, uniform syntax, powerful macros, and interactive REPL-based workflows that allow live inspection and modification of running programs. Haskell proponents counter that its strong static type system and dense, math-like syntax enable highly reliable code and expressive domain-specific languages, but critics find its syntax, laziness, and IO/monad model cumbersome for everyday debugging and “just add a print” iteration. Across languages, participants weigh trade-offs between dynamic flexibility and static safety, the practicality of hot-reloading in production, and how much syntax and tooling help or hinder real-world development.
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.