Clojure

A Dynamic Programming Language for the JVM

Rationale

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. Here's an outline of some of the motivating ideas behind Clojure.

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

Languages and Platforms

  • VMs, not OSes, are the platforms of the future, providing:
    • Type system
      • Dynamic enforcement and safety
    • Libraries
      • Abstract away OSes
      • Huge set of facilities
      • Built-in and 3rd-party
    • Memory and other resource management
      • GC is platform, not language, facility
    • Bytecode + JIT compilation
      • Abstracts away hardware
  • Language as platform vs. language + platform
    • Old way - each language defines its own runtime
      • GC, bytecode, type system, libraries etc
    • New way (JVM, .Net)
      • Common runtime independent of language
  • Language built for platform vs language ported-to platform
    • Many new languages still take 'Language as platform' approach
    • When ported, have platform-on-platform issues
      • Memory management, type-system, threading issues
      • Library duplication
      • If original language based on C, some extension libraries written in C don't come over
  • Platforms are dictated by clients
    • 'Must run on JVM' or .Net vs 'must run on Unix' or Windows
    • JVM has established track record and trust level
      • Now also open source
    • Interop with other code required
      • C linkage insufficient these days
  • Java/JVM is language + platform
    • Not the original story, but other languages for JVM always existed, now embraced by Sun
    • Java can be tedious, insufficiently expressive
      • Lack of first-class functions, no type inference, etc
    • Ability to call/consume Java is critical
  • Clojure is the language, JVM the platform

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 just 3 primary data structures (seq, map, vector).
  • Extend Java in Java, consume 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

Concurrency and the multi-core future

  • Immutability makes much of the problem go away
    • Share freely between threads
  • But changing state a reality for simulations and for in-program proxies to the outside world
  • Locking is too hard to get right over and over again
  • Clojure's software transactional memory does the hard part


In short, I think Clojure occupies a unique niche as a functional Lisp for the JVM with strong concurrency support. Check out some of the features.

 

Copyright © Rich Hickey