Clojure Truffle
A Clojure implementation on GraalVM Truffle, providing JIT compilation for Clojure programs.
This project implements Clojure as a Truffle language, enabling runtime JIT optimization through GraalVM's compiler infrastructure. It reuses clojure.lang data structures (persistent collections, Vars, Namespaces, etc.) from upstream Clojure while replacing the interpreter and compiler with a Truffle-based AST interpreter.
Features
- Truffle AST interpreter with JIT compilation via GraalVM
- Native image support with runtime JIT (Truffle Enterprise)
- Reuses upstream
clojure.langpersistent data structures compiled from source - Self-contained reader (
TruffleReader) and runtime (ClojureRT) with no dependency onclojure.lang.RTinitialization - No patches to GraalVM required (uses Feature API for native image configuration)
- REPL, file execution, and
-eexpression evaluation
Requirements
- GraalVM JDK 25+ (Oracle Enterprise Edition for native image with JIT)
- Maven 3.x
Build
JAVA_HOME=/opt/graalvm-jdk-25.0.1+8.1 mvn -f truffle/pom.xml package -q -DskipTests
This produces:
truffle/target/clojure-truffle-0.1.0-SNAPSHOT.jar(includesclojure.lang,clojure.asm, andclojure.truffle)truffle/target/dependency/(Truffle runtime JARs)
Run (JVM)
CP="truffle/target/clojure-truffle-0.1.0-SNAPSHOT.jar:$(echo truffle/target/dependency/*.jar | tr ' ' ':')" # Evaluate an expression java -Xss4m -cp "$CP" clojure.truffle.Main -e '(println (+ 1 2 3))' # Run a file java -Xss4m -cp "$CP" clojure.truffle.Main my_program.clj # Start a REPL java -Xss4m -cp "$CP" clojure.truffle.Main
Native Image (with JIT)
Build a native executable with Truffle JIT compilation enabled:
CP="truffle/target/clojure-truffle-0.1.0-SNAPSHOT.jar:$(echo truffle/target/dependency/*.jar | tr ' ' ':')" native-image -cp "$CP" \ clojure.truffle.Main --no-fallback \ --features=clojure.truffle.FixHostedOptionsFeature \ --initialize-at-build-time=clojure.truffle \ --initialize-at-run-time=sun.awt.X11 \ -H:+UnlockExperimentalVMOptions \ -H:-TruffleCheckBlockListMethods \ -H:DeadlockWatchdogInterval=300 -H:NumberOfThreads=4 \ -J-Xss8m \ -o clojure-truffle-jit
Run:
./clojure-truffle-jit -e '(println "hello")'Project Structure
truffle/
src/main/java/
clojure/lang/
TruffleReader.java # Self-contained Clojure reader (replaces LispReader)
clojure/truffle/
Main.java # Entry point (REPL, file, -e)
ClojureContext.java # Truffle language context and builtins
ClojureTruffleLanguage.java # Truffle language registration
FixHostedOptionsFeature.java # Native image Feature (JIT, continuations)
parser/
Analyzer.java # Clojure form -> Truffle AST compiler
runtime/
ClojureRT.java # RT replacement (no static initialization)
ClojureFunction.java # Truffle-optimized function objects
nodes/ # Truffle AST nodes
src/jvm/
clojure/lang/ # Upstream clojure.lang (compiled from source)
clojure/asm/ # Bundled ASM bytecode library
Architecture
The implementation consists of three layers:
-
clojure.lang(upstream) -- Persistent data structures, Vars, Namespaces, Symbols, Keywords. Compiled directly from source insrc/jvm/. TheRTclass has a minimal patch to skipclojure/core.cljloading when in Truffle mode. -
clojure.truffle.runtime--ClojureRTprovides static utility methods (seq,cons,list,map,get, etc.) without triggeringRT's static initializer.TruffleReaderis a self-contained Clojure reader with all necessary helper methods built in. -
clojure.truffle-- The Truffle language implementation.Analyzerparses Clojure forms into Truffle AST nodes.ClojureContextmanages namespaces, builtins, and var resolution. Truffle's partial evaluation and compilation pipeline handles JIT optimization.
License
Eclipse Public License 1.0 (same as Clojure). See epl-v10.html.