`compile` performs ahead-of-time (AOT) compilation of a Clojure library. It accepts the library path as a symbol, parses and evaluates its forms much like `load`, and writes generated Java class files to disk. The main method of `clojure.lang.Compile` provides a command-line route to the same kind of compilation. section 17.4 section 23.7
Compile a namespace
With `source.clj` available on the classpath and containing `(ns source)` and `(defn plus [x y] (+ x y))`, evaluate `(compile 'source)`; the result is `source`. The output directory, `*compile-path*`, defaults to `classes`. Its generated files include classes that initialize the namespace and its vars and a class for `plus`. section 17.4 section 23.7
;; mkdir mypath ;; export CLOJURE_JAR=~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar ;; java -cp $CLOJURE_JAR:mypath clojure.main ; #1 (spit "mypath/example.clj" "(ns example) (println \"example loaded\")") (binding [*compile-path* "mypath"] ; #2 (compile 'example)) ;; example loaded ;; example
For a different output directory, put the source namespace on the classpath and bind `*compile-path*` around `compile`. Compiling also evaluates the namespace: its print statement runs in this example. section 23.7
Use AOT when disk-backed classes help startup time or make Clojure code available to other JVM languages. It also enables `gen-class` declarations to produce Java classes. A class with a generated `main` method still needs a corresponding `-main` implementation; otherwise calling it raises an exception. AOT is not a universal default: generated classes are tied to a particular Clojure-JVM version, and deciding when to rebuild them adds build complexity. section 15.3 section 17.4
Compilation can also control what enters the output. Binding `clojure.test/*load-tests*` to `false` while compiling prevents accompanying `deftest` functions from being generated. In short, `compile` evaluates a library as `load` does, but additionally leaves reusable class files on disk. section 23.14 section 17.4
