Skip to end of metadata
Go to start of metadata

Problem statement

Given the current implementation of clojure.lang.RT which uses <cinit> behavior to compile clojure/core.clj with clojure.lang.Compiler it is impossible for 'Lean' Runtimes to escape the size and load time penalties associated with booting clojure.core from source. As clojure/core.clj will be compiled by the "official" dynamic compiler it's also impossible for lean applications to reap the full size and performance benifits of tree shaking and static linking as clojure/core.clj and the rest of the standard library will always be recompiled by the existing naive dynamic linking compiler.

Simply introducing lazy var initialization is insufficient as this still leaves a real overhead in terms of distributed application size and load time due to having to distribute and load all libraries and source code whether or not it will be used at runtime.

Proposed solution

Ideally, what is now the monolitic Clojure.core project would be partitioned into two or more artifacts representing abstractly the set of Java datastructures and interfaces in terms of Clojure's core is implemented, and another representing the Clojure reader, compiler and bootstrapping infrastructure. This partition would allow lean runtimes to statically compile an entire application including the Clojure core down to a set of Java classes which use no (or very very little) dynamic linking and to reap the full performance and size benifits of such linking by depending only on the Java classes and interfaces needed to implement the now statically compiled Clojure core.

This also has the side benifit of making it easier to experiment with Clojure derived languages and environments on the JVM by making the standard datastructures generally available in an official form rather than as a difficult to maintain userland fork such as krukow/clj-ds.