Jolt: Clojure compiler implemented with Chez Scheme
Jolt: A Clojure Implementation Powered by Chez Scheme
Jolt is a self-hosted implementation of Clojure that operates on Scheme. It utilizes Chez for native execution and Gambit for targeting JavaScript.
No JVM required and no mandatory build step—the vast majority of portable Clojure code runs exactly as written.
Core Capabilities
The compiler is authored in Clojure and is capable of compiling itself. It provides a comprehensive suite of Clojure semantics, including:
- Persistent data structures
- Lazy sequences
- Transducers
- Multimethods and Protocols
Real Concurrency: Jolt leverages OS threads for future, agent, pmap, and core.async, mirroring the behavior of the JVM. Furthermore, the jolt build command generates a single standalone binary, removing the need for a pre-installed Scheme or JVM environment.
Interactive Experience
If you visit the GitHub page, the terminal on the right is actually Jolt itself. It has been compiled to JavaScript via the Gambit backend and evaluates live in your browser.
Note: To keep the initial download lightweight, it uses a reduced build; consequently, regex is omitted (the system will notify you if you attempt to use it).
Example JS REPL Session:
user= (- (range 10) (filter even?) (map #(* % %)) (reduce +))
;; => 120
Why Choose Jolt?
🛠️ Self-Hosted Architecture
Jolt processes Clojure source, analyzes it into a host-neutral Intermediate Representation (IR), and then emits Scheme code.
📦 Standalone Binaries
Using jolt build, you can perform ahead-of-time (AOT) compilation. This bundles the application, its dependencies, the standard library, and the runtime into one executable.
🧵 Native Concurrency
The shared heap allows future, promise, agent, and pmap to run on actual OS threads, maintaining parity with JVM semantics.
🔢 Comprehensive Numeric Tower
Jolt supports a full range of numeric types:
- Exact integers and bignums.
- Exact ratios: is represented as
(/ 1 2). - Flonum doubles.
💾 Persistent Data & Compatibility
It implements immutable vectors (via 32-way tries), cons lists, and HAMT-based maps and sets. It remains compatible with:
- Lazy/infinite sequences
- Destructuring & Transducers
- Protocols, Records, and Multimethods
- Metadata and Namespaces
- The full Clojure reader and runtime
eval
Quick Start Guide
To get started, install the standalone binary which includes the compiler, runtime, and standard library.
Installation Options:
- Homebrew:
brew install jolt-lang/jolt/jolt - Shell Script (Linux/macOS):
curl -sL https://raw.githubusercontent.com/jolt-lang/jolt/main/install | bash - From Source (Requires Chez Scheme):
git clone --recurse-submodules https://github.com/jolt-lang/jolt.git cd jolt bin/jolt -e '(+ 1 2)' # => 3
Common Usage Patterns
| Action | Command |
|---|---|
| Evaluate | bin/jolt -e '(->> (range 10) (filter even?) (map (fn [x] (* x x))) (reduce +))' |
| Run Project | bin/jolt run -m myapp.core (resolves deps.edn) |
| Run Alias | bin/jolt -M:test [args] |
| Find Roots | bin/jolt path |
| Build Binary | bin/jolt build -m myapp.core -o myapp |
Pro Tip: Use --opt for optimized production builds or --dev for unoptimized development builds.
nREPL Integration
Start a server with bin/jolt --nrepl-server. This automatically resolves deps.edn and creates a .nrepl-port file. You can then connect via CIDER, Calva, or Cursive to perform REPL-Driven Development without restarting the process.
Divergences from Clojure (JVM)
While Jolt targets Clojure semantics, the shift from the JVM to Scheme introduces a few key differences:
| Aspect | Difference |
|---|---|
| Java Interop | No JVM means no general Java reflection or gen-class. However, a shimmed subset of java.* is provided, along with a C FFI. |
| BigDecimal | Not supported; (decimal?) always returns false. Other numeric tower features remain identical. |
| Regex | Powered by irregex instead of java.util.regex. Most patterns are compatible, but some Java-specific edge cases differ. |