Files
bara-lang/books/clojure-book/bg/05-clojure-nim.md
T
dimgigov 23252826a0 feat: add Clojure/Nim chapter to the book + restructure for GitLab
- 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
2026-05-08 23:32:11 +03:00

8.9 KiB
Raw Blame History

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)

Допълнително четене


Clojure/Nim е доказателство, че не ти трябва виртуална машина, за да пишеш елегантен, функционален, immutable код. Трябва ти само добър компилатор.