- New chapter 05-clojure-nim.md (EN + BG) covering: - Native compilation pipeline (Clojure → Nim → C → binary) - AI-powered development (error explanation, code generation) - JSON REPL for AI agents - loop/recur with real TCO - Cross-compilation: JS, shared libs, WASM - Persistent data structures (HAMT) - Concurrency: atoms, agents, channels - Updated book README.md with Clojure/Nim focus - Added Clojure/Nim terms to subject indices (EN + BG) - Removed books/ from .gitignore so it can be pushed to GitLab
8.9 KiB
Clojure/Nim: Native Clojure
Същият език, който обичаш. Компилиран до нативен код. Без JVM.
Какво е Clojure/Nim?
Clojure/Nim е пълен диалект на Clojure, който се компилира до нативен машинен код през Nim компилатора. Това не е интерпретатор — това е истински компилатор с пълен pipeline за оптимизация:
Твоят .clj файл
↓
Reader (EDN парсер)
↓
Разширяване на макроси (defmacro, syntax-quote, ->, ->>)
↓
Emitter (Clojure AST → Nim изходен код)
↓
Nim компилатор → C код
↓
C компилатор → Нативен бинарен файл
Резултатът е един изпълним файл, често под 1 MB, който стартира мигновено — без JVM warmup.
Защо native?
| JVM Clojure | Clojure/Nim |
|---|---|
| Нуждае се от Java runtime | Самостоятелен бинарен файл |
| ~2-5 секунди startup | Мигновен старт |
| ~100-300 MB RAM | ~1-10 MB |
| JIT паузи | Ahead-of-time, предсказуем |
| Идеален за сървъри | Идеален за CLI, embedded, WASM |
Това не е играчка. Това е production компилатор с 276+ теста, persistent структури от данни (HAMT), core.async канали и AI-асистиран workflow.
Инсталация
git clone https://gitlab.com/balvatar/lisp-nim.git
cd lisp-nim
make build
make check # всички тестове + примери
Изисквания: Nim ≥ 2.0, GCC или Clang, make.
Толкова. Няма Java. Няма Leiningen. Няма deps, които се свалят по десет минути.
Първа програма
Създай hello.clj:
(println "Здравей от native Clojure!")
(println (+ 1 2 3 4 5))
Изпълни:
$ ./cljnim run hello.clj
Здравей от native Clojure!
15
Забележи: програмата беше парсирана, разширена с макроси, емитирана като Nim, компилирана до C, компилирана до машинен код и изпълнена — всичко за под секунда.
REPL: Два режима
Човешки REPL
$ ./cljnim repl
user> (defn square [x] (* x x))
user> (square 7)
=> 49
user> (atom 42)
=> (atom 42)
user> :ai функция за фибоначи
🤖 Мисля...
💡 AI Предложение:
(defn fib [n]
(loop [a 0 b 1 i 0]
(if (= i n) a (recur b (+ a b) (inc i)))))
JSON REPL (за AI агенти)
$ ./cljnim repl --json
{"status":"ready","ns":"user","mode":"json"}
> {"op":"eval","form":"(+ 1 2 3)"}
{"status":"ok","result":{"printed":"6"},"meta":{"ms":12}}
> {"tool":"cljnim/eval","args":{"form":"(defn greet [name] (str \"Hello \" name))"}}
{"status":"ok","result":{"type":"var","name":"greet"},...}
JSON REPL е проектиран за програмно взаимодействие. Всяка операция има структуриран вход и изход. AI агенти могат да откриват възможности, оценяват код, инспектират дефиниции и обработват batch форми без парсиране на човешки текст.
AI-асистирана разработка
Clojure/Nim е първата Clojure имплементация, в която AI асистенцията е първокласна функция.
Обяснение на грешки
Когато компилацията fail-не, компилаторът пита AI за помощ:
$ ./cljnim run broken.clj
Compilation failed
Error: identifier expected, but got 'keyword var'
💡 AI Предложение:
Грешката е защото `var` е запазена дума в Nim.
Оправи: Преименувай функцията на `my-var`.
Генериране на код
Генерирай идиоматичен Clojure от описание:
$ ./cljnim ai "функция, която филтрира четните числа"
(defn filter-even [coll]
(loop [remaining coll result []]
(if (empty? remaining)
result
(let [x (first remaining)]
(recur (rest remaining)
(if (even? x) (conj result x) result))))))
Настройка
export DEEPSEEK_API_KEY="sk-..."
# или OPENAI_API_KEY, или MIMO_API_KEY
loop / recur: Истинска TCO
За разлика от JVM Clojure (който използва recur, за да избегне stack overflow, но все пак работи върху stack-based VM), Clojure/Nim компилира loop/recur до native while цикъл:
(defn factorial [n]
(loop [acc 1 i n]
(if (= i 0)
acc
(recur (* acc i) (dec i)))))
Това генерира ефективен C код без функционални извиквания. Истински O(1) stack space.
Cross-Compilation Target-и
Clojure/Nim може да таргетира множество платформи от един и същи изходен код:
Нативен бинарен файл (по подразбиране)
./cljnim run program.clj
JavaScript
./cljnim compile program.clj program.nim
nim js -o:program.js program.nim
node program.js
C Shared Library
./cljnim compile-lib program.clj program.nim
nim c --app:lib -o:libprogram.so program.nim
WASM (експериментално)
nim c -d:release --cpu:wasm32 --os:linux program.nim
Това е нещо, което JVM Clojure просто не може да направи.
Persistent Структури от Данни
Clojure/Nim имплементира истински Hash Array Mapped Trie (HAMT) вектори и карти:
(def v (vector 1 2 3))
(def v2 (conj v 4))
;; v => [1 2 3]
;; v2 => [1 2 3 4]
;; Structural sharing: O(log₃₂ n) обновления, не O(n) копия
Runtime-ът използва същите алгоритми като Clojure/JVM (32-way branching, path copying, tail optimization), но компилиран до bare metal.
Конкурентност
Atoms
(def counter (atom 0))
(swap! counter inc) ;; => 1
(reset! counter 100) ;; => 100
(deref counter) ;; => 100
Agents
(def state (agent 0))
(send state + 10)
(await state)
(deref state) ;; => 10
Канали (core.async)
(def ch (chan 10))
(put! ch 42)
(take! ch) ;; => 42
(close! ch)
Всички примитиви за конкурентност работят както в компилирания runtime, така и в in-memory интерпретатора.
Макроси, които работят
(defmacro unless [condition body]
`(if (not ~condition)
~body))
(unless false
(println "Това се печата!"))
Threading макроси, when-let, cond, doto, some-> — всички имплементирани като истински Clojure макроси, разширявани по време на компилация.
Кога да използваш Clojure/Nim
| Use Case | Clojure/JVM | Clojure/Nim |
|---|---|---|
| Големи уеб услуги | ✅ | ⚠️ (ранен етап) |
| CLI инструменти | ⚠️ (бавен старт) | ✅ (мигновен) |
| Embedded системи | ❌ | ✅ |
| WASM / браузър | ClojureScript | ✅ (native WASM) |
| Споделени библиотеки | ❌ | ✅ |
| AI agent scripting | ❌ | ✅ (JSON REPL) |
| Учене на Clojure | ✅ | ✅ (без JVM) |
Допълнително четене
- Основи — Core Clojure концепции (валидни за всички диалекти)
- Архитектура — Как работи компилаторът вътрешно
- AI Интеграция — Детайли за AI функциите
- API Справочник — Спецификация на JSON REPL протокола
Clojure/Nim е доказателство, че не ти трябва виртуална машина, за да пишеш елегантен, функционален, immutable код. Трябва ти само добър компилатор.