Skip to end of metadata
Go to start of metadata

Clojure is not an interpreter. In order to be run, Clojure source code must be compiled into Java bytecode. This is the job of the Reader and Compiler together. When you "load" a .clj source file, or type expressions into the Clojure REPL, the Compiler generates Java bytecode and loads it into the Java Virtual Machine (JVM), where it can be executed.

Since release 1.0, Clojure has supported "ahead-of-time" (AOT) compilation. "Ahead-of-time" means that all the Java bytecode is generated in advance and stored on disk, in Java .class files. In theory, ahead-of-time compilation allows a Clojure application to start in less time, because the Reader and Compiler do not have to do any work. But the Compiler is pretty fast, so the difference tends to be small.

So why wouldn't you ahead-of-time compile everything? There's a problem: the JVM bytecode emitted by the Compiler contains explicit references to internals of the Clojure language runtime, such as class names and method calls. These internals, while invisible to Clojure source code, have changed slightly with each Clojure release: 1.1, 1.2, and (alpha) 1.3.

Clojure has remained source-compatible since 1.0. Clojure source code written for Clojure 1.0 should work, unchanged, with 1.1, 1.2, and 1.3. But .class files that were ahead-of-time compiled with Clojure 1.0 will not work with later Clojure versions.

This has been a big problem for Clojure library authors. To ensure maximum compatibility across all released versions of Clojure, many Clojure library authors have adopted the convention of distributing their libraries as JAR files containing only .clj sources. Application developers who want to minimize load time for their applications must manually ahead-of-time compile those libraries when building their applications.

While not ideal, this is the best way we have at the moment to ensure that Clojure libraries are usable by the greatest number of people.

Some libraries may require ahead-of-time in order to function correctly, especially if they make use of gen-class to interoperate with Java. There is no perfect solution for ahead-of-time compiling a subset of the Clojure sources in a library, but this is an active research area. See Loading, Compiling, and Namespaces for more details.