Differences with other Lisps

This information is provided for programmers familiar with Common Lisp or Scheme.


  • Clojure is case sensitive
  • Clojure is a Lisp-1
  • () is not the same as nil
  • The reader is side-effect free
  • Keywords are not Symbols
  • Symbols are not storage locations (see Var)
  • nil is not a Symbol
  • t is not syntax, use true
  • The read table is currently not accessible to user programs
  • let binds sequentially
  • do is not a looping construct
  • There is no tail-call optimization, use recur.
  • syntax-quote does symbol resolution, so `x is not the same as 'x.
  • ` has auto-gensyms.
  • ~ is unquote ',' is whitespace
  • There is reader syntax for maps and vectors
  • cons, first and rest manipulate sequence abstractions, not concrete cons cells
  • Most data structures are immutable
  • lambda is fn, and supports overloading by arity
  • eql? is the equality predicate
  • All (global) Vars can be dynamically rebound without interfering with lexical local bindings. No special declarations are necessary to distinguish between dynamic and lexical bindings. Since Clojure is a Lisp-1, (global) functions can be dynamically rebound.
  • No letrec, labels or flet - use (fn name [args]...).
  • In Clojure nil means 'nothing'. It signifies the absence of a value, of any type, and is not specific to lists or sequences.
  • Empty collections are distinct from nil. Clojure does not equate nil and '().
  • false means one of the two possible boolean values, the other being true
  • There is more to collections than lists. You can have instances of empty collections, some of which have literal support ([], {}, and ()). Thus there can be no sentinel empty collection value.
  • Coming from Scheme, nil may map most closely to your notion of #f.
  • A big difference in Clojure, is sequences. Sequences are not collections, esp. they are not concrete lists. There is no such thing as an empty sequence. Either there is a sequence (with elements) or there isn't (nil). When you ask an empty collection for a sequence of its elements it returns nil, saying "I can't produce one". When you ask a sequence on its last element for the rest it returns nil, saying, "there is no more".
  • Some of the sequence functions correspond to functions from Scheme and CL that there manipulated only pairs/conses ('lists') and returned sentinel values ('() and nil) that represented 'empty' lists. The Clojure return values differ in not returning empty collections, but rather a sequence or not. Some of the sequence functions have no counterpart in Scheme/CL, and map to Haskell/ML-like functions. Some of those functions return infinite or calculated sequences, where the analogy to concrete data-structures like Scheme/CL lists is tenuous at best.
  • It helps to distinguish collections/data-structures and seqs/iteration. In both CL and Scheme they are conflated, in Clojure they are separate.

  Clojure Common Lisp Scheme Java
Has nil? nil - means 'nothing' nil - means false or empty list - null
Has true? true - #t true (primitive)
Has false? false - #f false (primitive)
Conditionals distinguish: nil or false/ everything else nil/non-nil #f/non-#f false/true
List/sequence library manipulates distinguished concrete type(s)? No - seq abstraction with many collection implementations Yes - cons and vector Yes - pair No - Iterator abstraction with many collection implementations
Singleton empty-list value? No - can have distinct empty values of concrete collection types nil '() No
End-of-sequence returns: nil nil '() false
Host null: nil NA NA NA
Host true: true (boxed) NA NA NA
Host false: false (boxed) NA NA NA

Copyright © Rich Hickey