clojure source code as EDN data
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


clojure source code as EDN data


  • this is WIP in both design and implementation, but passes all the tests inherited from tools.reader
  • the current implementation is frankenstein-ed off of (Thanks!) and neither elegant or consistent
  • look in the test/codn/parser directory for more examples


Clojure's built-in readers both parse source code, and interpret reader macros such as ` (syntax-quote).

This means the result of read is a) a derivative of the source code, rather than a literal representation, and b) tied to the environment in which the read is performed.

These two characteristics of clojure's readers make them unsuitable for tasks such as source code analysis, and dynamic code distribution in distributed systems.

Codn (COde as eDN) transliterates clojure source code into a strict EDN subset, allowing the source code to be treated as pure data.


The objectives of codn are:

  • represent clojure source code as pure EDN data
  • provide a basis for source code analysis
  • provide a basis for implementing sub-codeqs in codeq
  • provide a basis for multipass analysis and compilation
  • provide a safe, analyzable basis for code exchange in distributed systems
  • cleanly interoperate with term rewriting / tree transformation libraries

It is a non-objective of codn to provide isomorphic representation of textual documents containing source code. While codn is potentially useful for IDEs and editors, the goal is not to represent the document containing the program, but the program itself.


Codn provides facilities for parsing source code into the codn format, and for reading codn data into their corresponding runtime structures.

Add codn to your project dependencies:

[codn/codn "0.1.0-SNAPSHOT"]


load parser namespace:

(require '[codn.parser.core :as p])

Primitives return a form {:head primitive-type-keyword :value primitive-value}

(p/parse-string "a")
=> {:head :symbol, :value a}

Compound structures return a form {:head compound-type-keyword :body [components..]}

(p/parse-string "[a]")
=> {:head :vector, :body [{:head :symbol, :value a}]}

(p/parse-string "(deref a)")
=> {:head :list, :body [{:head :symbol, :value deref} {:head :symbol, :value a}]}

Reader macros and other non-EDN syntaxes are parsed into compound structures, differentiated by their :head :

(p/parse-string "`a")
=> {:head :syntax-quote, :body [{:head :symbol, :value a}]}

(p/parse-string "@a")
=> {:head :deref, :body [{:head :symbol, :value a}]}

(p/parse-string "[1]")
=> {:head :constructor, :body [{:head :symbol, :value} {:head :vector, :body [{:head :integer, :value 1}]}]}


load reader namespace:

(require '[codn.reader.core :as r])

(r/read-codn '{:head :vector, :body [{:head :symbol, :value a}]})
=> [a]