dimgigov 549e04f24d feat: +12 tests (210/233, 90%) — fn wrapping, doseq, when-first, NaN?, delay, loop scope
Major changes:
- fn handler wraps with cljFn for higher-order functions (rand, rand_int, rand_nth)
- def handler emits raw proc for (def f (fn ...)) context
- Local fn calls use .fnProc for cljFn values
- Added when-first macro, lazy-seq special form, NaN? predicate
- Added delay, rseq, listEmpty runtime functions
- doseq macro uses next instead of rest, recur inside when body
- loop handler pushScope/popScope for proper variable scoping
- let handler: var/while/proc statement checks, block last-line discard
- when handler: proper statement detection for body forms
- defn/defn- allow empty body
2026-05-09 23:17:02 +03:00

Clojure/Nim

A Clojure dialect that compiles to Nim → C → native binaries.

JVM Clojure Clojure/Nim
JVM required No
GraalVM/native-image No
Google Closure Compiler No
Java stdlib dependency No
Startup time Slow (JVM warmup) Instant
Binary size 50MB+ < 1MB

Tests Nim License

Quick Start

git clone https://gitlab.com/balvatar/lisp-nim.git
cd lisp-nim
make build
make check
./cljnim run examples/hello.clj

Documentation

What is this?

Clojure/Nim is an AI-first Clojure implementation targeting the Nim ecosystem. It compiles Clojure source directly to Nim, then to C, and finally to a native binary.

Unlike every other Clojure dialect, this project has zero dependency on the Java ecosystem:

Dialect JVM? Java Ecosystem Dependency
Clojure (JVM) Required Full — runs on JVM, uses Java stdlib
ClojureScript Heavy — Google Closure Compiler, JS ecosystem
Babashka Medium — GraalVM native-image, still JVM-based
Clojure/Nim None — completely standalone

Why?

  • Native Performance — No JVM warmup, no GC pauses, C-speed execution
  • Tiny Binaries — Single-file executables, often under 1MB
  • Nim Ecosystem — Direct access to Nim and C libraries via FFI
  • AI-Native — JSON REPL, batch evaluation, AI-assisted error messages and code generation
  • True Independence — No JVM, no GraalVM, no Java stdlib, no Google Closure

What Makes This Unique?

1. Completely Independent from Java

This is the only Clojure dialect that does not depend on any part of the Java ecosystem — not the JVM, not GraalVM, not the Java standard library, and not Google Closure Compiler. The entire toolchain is self-contained: Clojure source → Nim source → C source → native binary.

2. Native HAMT Persistent Data Structures

Built from scratch in Nim:

  • Persistent Vector — Hash Array Mapped Trie with 32-way branching and structural sharing
  • Persistent Map — HAMT-based immutable hash map, O(log₃₂ n) operations
  • Persistent Set — Backed by HAMT map
  • Transients — Batch mutations with conj!, assoc!, persistent!

No Java PersistentVector.java or IPersistentMap interfaces — our own implementation optimized for Nim's memory model and ORC garbage collector.

3. Multiple Compilation Targets from One Codebase

The same Clojure code compiles to:

Target Status Use Case
Native binary Ready CLI tools, system programming, servers
Native shared library (.so/.dll/.dylib) Ready Embed Clojure in Python/Rust/Go/C via FFI
WASM Ready Browser, serverless, edge computing
JavaScript Ready Frontend, Node.js without 50MB JVM

4. AOT Compiler — Not an Interpreter

Full ahead-of-time compilation like ClojureScript, but without the JavaScript/Google Closure dependency:

  • Fast runtime execution at C speed
  • Small binary sizes with no interpreter overhead
  • REPL uses a hybrid model: tree-walking interpreter for fast feedback (<1ms eval), AOT compilation for production builds

5. Nim/C Interop Instead of Java Interop

Direct FFI to the Nim and C ecosystem:

(nim/math/sin x)
(nim/strutils/toUpper s)

Nim modules are auto-imported. No JNI, no JVM bridging, no Java interop overhead.

6. AI-Native Tooling Built-In

  • AI-assisted errors — DeepSeek/MiMo explain compiler errors
  • AI code generation(ai/generate "quicksort") in REPL
  • AI optimization hints(ai/optimize code) suggests algorithm improvements
  • AI debugging(ai/debug expr) analyzes runtime behavior
  • JSON REPL protocol — Structured I/O designed for AI agents and IDE integration

7. Concurrency Without the JVM

  • Atoms — Compare-and-swap semantics
  • Agents — Async state updates with send/await
  • core.async channelschan, >!, <!, go macros — CSP-style concurrency without JVM threads

Key Features

Feature Status
Compiler (Clojure → Nim → C → native)
REPL with JSON protocol
Macro system (defmacro, syntax-quote, ->, ->>)
Persistent data structures (HAMT vector/map/set)
Transients for batch mutations
Atoms, Agents, Channels
loop/recur
try/catch/finally
Namespace system (ns, :require)
Dependency resolution (deps.edn, Git deps)
Nim/C FFI interop
AI integration (DeepSeek, OpenAI, MiMo)
Cross-compilation targets (JS, WASM, shared libs)
Self-hosted REPL with tree-walking interpreter
276+ tests

Example

;; examples/math.clj
(defn factorial [n]
  (if (= n 0)
    1
    (* n (factorial (- n 1)))))

(println (factorial 5))  ;; => 120
$ ./cljnim run examples/math.clj
120

AI-Powered Development

export DEEPSEEK_API_KEY="sk-..."
./cljnim ai "function that sums a list using loop/recur"

See docs/en/03-ai-integration.md for details.

License

MIT — see LICENSE

S
Description
Clojure - NIM
Readme MIT 609 KiB
Languages
Nim 88.4%
JavaScript 8.1%
Shell 1.5%
Python 0.8%
HTML 0.6%
Other 0.6%