20.1 Why Clojure?
Why did I write yet another programming language? Basically because I wanted:
- A Lisp
- for Functional Programming
- symbiotic with an established Platform
- designed for Concurrency
and couldn’t find one.
Lisp is a good thing
- Often emulated/pillaged, still not duplicated
- Lambda calculus yields an extremely small core
- Almost no syntax
- Core advantage still code-as-data and syntactic abstraction
- What about the standard Lisps (Common Lisp and Scheme)?
- Slow/no innovation post standardization
- Core data structures mutable, not extensible
- No concurrency in specs
- Good implementations already exist for JVM (ABCL, Kawa, SISC et al)
- Standard Lisps are their own platforms
- Clojure is a Lisp not constrained by backwards compatibility
- Extends the code-as-data paradigm to maps and vectors
- Defaults to immutability
- Core data structures are extensible abstractions
- Embraces a platform (JVM)
Functional programming is a good thing
- Immutable data + first-class functions
- Could always be done in Lisp, by discipline/convention
- But if a data structure can be mutated, dangerous to presume it won’t be
- In traditional Lisp, only the list data structure is structurally recursive
- Pure functional languages tend to strongly static types
- Not for everyone, or every task
- Clojure is a functional language with a dynamic emphasis
- All data structures immutable & persistent, supporting recursion
- Heterogeneous collections, return types
- Dynamic polymorphism
Object Orientation is overrated
- Born of simulation, now used for everything, even when inappropriate
- Encouraged by Java/C# in all situations, due to their lack of (idiomatic)
support for anything else
- Mutable stateful objects are the new spaghetti code
- Hard to understand, test, reason about
- Concurrency disaster
- Inheritance is not the only way to do polymorphism
- "It is better to have 100 functions operate on one data structure than to
have 10 functions operate on 10 data structures." - Alan J. Perlis
- Clojure models its data structures as immutable objects represented by
interfaces, and otherwise does not offer its own class system.
- Many functions defined on few primary data structures (seq, map, vector,
set).
- Write Java in Java, consume and extend Java from Clojure.
Polymorphism is a good thing
- Switch statements, structural matching etc yield brittle systems
- Polymorphism yields extensible, flexible systems
- Clojure multimethods decouple polymorphism from OO and types
- Supports multiple taxonomies
- Dispatches via static, dynamic or external properties, metadata, etc