We assume that the development environment is either Linux or macos.

  1. Make sure you have Java runtime environment installed.
  2. Download the lein script. It is the compiler toolchain.
  3. Run lein as an executable script, and it will automatically install the necessary Clojure compiler and libraries.

Create a project

$ lein new hello-world

Generating a project called hello-world based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.

The empty project has a function declared foo which we can choose to run:

$ lein run -m hello-world.core/foo Blah   
Blah Hello, World!

Clojure error messages are ugly

Suppose we inject a run-time error into foo:

(defn foo [x]
  (println (* x 2) ": hello world"))

This leads to a run-time error, and with a rather unreadable stack trace.

    $ lein run -m hello-world.core/foo Blah
    Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot
    be cast to java.lang.Number,
        at clojure.lang.Compiler.load(
        at clojure.lang.Compiler.loadFile(
        at clojure.main$load_script.invokeStatic(main.clj:275)
        at clojure.main$init_opt.invokeStatic(main.clj:277)
        at clojure.main$init_opt.invoke(main.clj:277)
        at clojure.main$initialize.invokeStatic(main.clj:308)
        at clojure.main$null_opt.invokeStatic(main.clj:342)
        at clojure.main$null_opt.invoke(main.clj:339)
        at clojure.main$main.invokeStatic(main.clj:421)
        at clojure.main$main.doInvoke(main.clj:384)
        at clojure.lang.RestFn.invoke(
        at clojure.lang.Var.invoke(
        at clojure.lang.AFn.applyToHelper(
        at clojure.lang.Var.applyTo(
        at clojure.main.main(
    Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to
        at clojure.lang.Numbers.multiply(
        at clojure.lang.Numbers.multiply(
        at hello_world.core$foo.invokeStatic(core.clj:6)
        at hello_world.core$foo.invoke(core.clj:3)
        at clojure.lang.Var.invoke(
        at user$eval2820.invokeStatic(form-init1872070180712311231.clj:1)
        at user$eval2820.invoke(form-init1872070180712311231.clj:1)
        at clojure.lang.Compiler.eval(
        at clojure.lang.Compiler.eval(
        at clojure.lang.Compiler.load(
        ... 14 more

The reason that the stack trace so unreadable is because it is generated by the Java VM.

Leiningen’s project.clj

Leiningen uses Clojure data structure to configure the project.

We will add a really cool stack trace formatter.

(defproject hello-world "0.1.0-SNAPSHOT"
  :plugins [[io.aviso/pretty "0.1.34"]]
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [io.aviso/pretty "0.1.34"]])

Let’s run the erroneous foo function.

    $ lein run -m hello-world.core/foo Blah
    1 ↵
    Uncaught exception in thread main:
           clojure.main.main  37
           clojure.main/main   main.clj: 384
           clojure.main/main   main.clj: 421
       clojure.main/null-opt   main.clj: 342
     clojure.main/initialize   main.clj: 308
       clojure.main/init-opt   main.clj: 277
    clojure.main/load-script   main.clj: 275
               user/eval3108  REPL Input    
        hello-world.core/foo   core.clj:   6
               java.lang.ClassCastException: java.lang.String cannot be cast to
    clojure.lang.Compiler$CompilerException: java.lang.ClassCastException:
    java.lang.String cannot be cast to java.lang.Number,
comments powered by Disqus