I recently made a contribution to ghijira, a small tool written in Clojure for exporting issues from GitHub in JIRA-compatible format. One of the problems to solve there was loading configuration from file.

Originally, it used have a separate config.clj file that looked like this:

(def auth "EMAIL:PASS") (def ghuser "user-name") (def ghproject "project-name") (def user-map { "GithubUser1" "JIRAUser1" "GithubUser2" "JIRAUser2"})

Then it was imported in place with:

(load-file "config.clj")

I did not like it, because it did not feel very functional and the configuration file had too much noise (isn’t def form manipulation too much for a configuration file?).

For a moment I thought about using standard Java .properties files. They get the job done, but they’re also somewhat rigid and unwieldy.

It occurred to me I really could use something similar to Leiningen and its project.clj files: Make the config a plain Clojure map. It’s very flexible with minimal syntax, and it’s pure data just like it should be.

From a quick Google search I found the answer at StackOverflow.

It turns out I can rewrite my configuration file to:

{:auth "EMAIL:PASS" :ghuser "user-name" :ghproject "project-name" :user-map { "GithubUser1" "JIRAUser1" "GithubUser2" "JIRAUser2" } }

And then load it in Clojure with read :

(defn load-config [filename] (with-open [r (io/reader filename)] (read (java.io.PushbackReader. r))))

That’s it, just call read .

I find this solution a lot more elegant and “pure”.

By the way, this data format is getting a life of its own, called Extensive Data Notation. The Relevance team has even published a library to use EDN in Ruby.