S-Expression evaluation library for Clojure and ClojureScript
Clojure JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



An S-Expression evaluation library for Clojure and ClojureScript. Unlike Clojure's eval, Quiddity lets you work with limited forms using user-specified environment.


On Clojars: https://clojars.org/quiddity

Leiningen dependency: [quiddity "0.2.0"]

Supported Clojure versions: 1.2, 1.3, 1.4, 1.5

Tested with lein-cljsbuild version: 0.2.8


You can invoke Quiddity evaluation with quiddity.core/evaluate:


(evaluate form env err-h)
  • form is a valid Clojure form
  • env is user-specified environment -- a collection of maps for value lookup
  • err-h is error handler (function that accepts error message and deals with it)

Clojure example:

(evaluate (read-string "(inc (dec (+ n 10)))") [{:+ + :inc inc :dec dec :n 20}]
          #(throw (RuntimeException. %)))

ClojureScript example:

(evaluate (cljs.reader/read-string "(inc (dec (+ n 10)))") [{:+ + :inc inc :dec dec :n 20}]
          #(throw (js/Error %)))

How lookup works

The symbol values are looked up in each of the maps in env. When not found in any of them, the error handler is called with the error message as argument.

The expression symbols can be present in env as keys, or their corresponding keywords as the keys. For example, (foo 42) will look for both 'foo and :foo as a key in env.


Quiddity supports only limited forms in the S-expressions it evaluates. The following are not supported (note that shortcuts to special forms eg. ', #', #(...), @ etc. are automatically expanded by the reader):

  • Special forms (some are re-implemented using evaluator, see Evaluator)
  • Macros (some are re-implemented using evaluator, see Evaluator)
  • Destructuring (re-implemented using evaluator, see Evaluator)
  • Classnames (they are treated as ordinary symbols)
  • Creating functions (re-implemented using evaluator, see Evaluator)
  • Namespaces


In order to make up for some of the limitations listed above, Quiddity supports something called an evaluator. An evaluator is an annotated function that

  • accepts env as first argument
  • accepts remaining arguments as listed in the expression
  • is responsible for evaluating the arguments

Evaluators may appear at any levels of the S-expression. You can use quiddity.core/make-evaluator, eg. (make-evaluator fn-object) to annotate a function as an evaluator. Evaluators are passed as part of env during evaluation just like other functions. However, they are treated specially during invocation.

The following evaluators are provided in quiddity.lib/all (map):

  • Special forms equivalent
    • do
    • if
    • quote
  • Macros equivalent
    • ->
    • ->>
    • and
    • case
    • cond
    • condp
    • fn with destructuring, without pre and post conditions
    • for-each with destructuring (same as for without :let, :when, :while forms)
    • if-not
    • let with destructuring
    • or
    • when
    • when-not
    • while
  • Function equivalent
    • deref a.k.a @


Running tests

Clean older stuff if any (required for ClojureScript testing)

lein dev clean

Run the tests

lein dev test  # test with Clojure & ClojureScript (needs `phantomjs` installed)
lein all test  # test with all supported Clojure versions

Building a JAR (and installing to local repo)

lein jar     # create the JAR file
lein install # install JAR to local Maven repo

Getting in touch

On Twitter: @kumarshantanu

E-mail: kumar(dot)shantanu at gmail.com


Copyright © 2012 Shantanu Kumar

Distributed under the Eclipse Public License, the same as Clojure.