Files
bara-lang/ARCHITECTURE.md
T
2026-05-08 14:51:47 +03:00

170 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура: Истински Clojure върху Nim
## Философия
Това не е "Clojure-подобен" език. Това е **Clojure диалект**, който компилира към Nim.
Макросите, структурите от данни и семантиката са съвместими с Clojure (JVM).
### Защо истински Clojure?
| Аспект | Clojure-inspired Lisp | Истински Clojure диалект |
|---|---|---|
| **Библиотеки** | Пишеш всичко на ново | Можеш да пренесеш `clojure.core`, `clojure.string`, `clojure.set` |
| **Разработчици** | Учат нов език | Всеки Clojure програмист може да го ползва веднага |
| **Инструменти** | Собствени | Работи с `clojure-mode`, CIDER, Calva (с някои адаптации) |
| **Финтех/Indустрия** | Не е опция | Може да се ползва за реални проекти |
### Който го е правил успешно
- **ClojureScript** — компилира Clojure до JS. Използва Google Closure. Пълна съвместимост.
- **Babashka** — GraalVM native image на Clojure. Бърз старт, скриптове, портативен.
- **Ferret** — Clojure → C++11 за embedded системи. Работи на 2KB RAM.
- **ClojErl** — Clojure върху BEAM. Жертва част от performance заради семантиката.
## Архитектура на Компилатора
```
┌─────────────────┐
│ .clj Файл │ ← Стандартен Clojure код
└────────┬────────┘
┌────▼────┐
│ Reader │ ← EDN парсер, Clojure symbols, quoted forms
└────┬────┘
┌────▼────┐
│ Macro │ ← defmacro, syntax-quote, unquote, unquote-splicing
│ Expansion│ (работи върху Clojure структури)
└────┬────┘
┌────▼────┐
│ Analyzer│ ← Специални форми, locals, recur targets,
│ │ closures, type hints
└────┬────┘
┌────▼────┐
│ Emitter │ ← Генерира Nim AST (не Nim текст!)
│ (Nim) │ Използва Nim макроси за компилация
└────┬────┘
┌────▼────┐
│ Nim │ ← C код, после машинен код
│Compiler │ оптимизация, tree-shaking, LTO
└────┬────┘
┌────▼────┐
│ Бинарен │ ← Единичен файл, < 10MB, бърз старт
│ Файл │
└─────────┘
```
## Ключови Решения
### 1. Компилатор, не Интерпретатор
Изборът е **AOT компилатор**, подобно на ClojureScript. Няма да пишем интерпретатор в Nim.
- **Предимство:** Бърз runtime, малък footprint, компилира до C.
- **Недостатък:** REPL е по-труден (но не невъзможен — виж ClojureScript self-hosted).
- **Урок от calcit-runner:** Те започнаха с интерпретатор в Nim и се провалиха. Ние директно компилираме.
### 2. Clojure Макроси на Clojure Структури
```clojure
;; Това трябва да работи без промяна:
(defmacro unless [condition & body]
`(if (not ~condition)
(do ~@body)))
(unless false
(println "Работи!"))
```
Макросите се разширяват **преди** да стигнем до Nim. Nim никога не вижда Clojure макрос.
### 3. Persistent Структури от Данни в Nim
Clojure's Hash Array Mapped Trie (HAMT) трябва да се имплементира в Nim:
```nim
# Nim runtime за Clojure Vector
type
NodeKind = enum nkLeaf, nkInternal
Node[T] = ref object
case kind: NodeKind
of nkLeaf: values: seq[T]
of nkInternal: children: array[32, Node[T]]
PersistentVector[T] = object
root: Node[T]
tail: seq[T]
count: int
```
- `conj`, `assoc`, `dissoc` — O(log₃₂ n)
- `nth`, `get` — O(log₃₂ n)
- `count` — O(1)
### 4. Nim Interop (вместо Java Interop)
Тъй като нямаме JVM, interop-ът е с Nim:
```clojure
;; Извикване на Nim функция
(nim/strutils.join ", " ["a" "b" "c"])
;; Достъп до Nim тип
(nim/times.DateTime)
;; FFI към C библиотека
(nim/ffi.import "math.h" :functions [["sin" :double [:double]]])
```
### 5. Симулация на Clojure Runtime
| Clojure JVM | Нашата Имплементация |
|---|---|
| `Var` | Глобални Nim променливи с atomic CAS |
| `Namespace` | Nim модул + хеш таблица със символи |
| `Atom` | `ref` тип с compare-and-swap |
| `Agent` | Channel + Worker thread |
| `Ref/STM` | Software transactional memory в Nim |
| `Multimethod` | Диспач таблица + `isa?` проверка |
| `Protocol` | Nim concepts + dispatch таблица |
## Фази с Индустриален Фокус
### Phase 1: Компилатор (не REPL!)
Фокус: AOT компилация на прости Clojure файлове към Nim.
### Phase 2: Core Библиотека
Фокус: Пренасяне на `clojure.core` функции. Тестове с реални Clojure тестове.
### Phase 3: Nim Interop + FFI
Фокус: Извикване на Nim/C библиотеки. Това е нашето "убийствено" предимство.
### Phase 4: REPL (Self-hosted)
Фокус: REPL като ClojureScript (компилира в паметта).
### Phase 5: Инструменти
Фокус: nREPL съвместимост, LSP, пакетен мениджър (Nimble интеграция).
## Изисквания за Съвместимост
- `clojure.core` namespace трябва да е наличен
- `defn`, `let`, `if`, `do`, `recur`, `loop` — точна семантика
- `->`, `->>`, `cond->` — макроси
- Persistent Vector, Map, Set — стандартни операции
- Keywords (`:name`) и Symbols (`'sym`) — interned
## Разлики от JVM Clojure (приемливи)
| JVM Clojure | Clojure/Nim |
|---|---|
| Java interop | Nim interop |
| JVM threads | Nim threads (no GIL!) |
| Dynamic classloading | AOT компилация |
| `gen-class` | `gen-nim` (генериране на Nim типове) |
| Reflection | Compile-time метаданни |
| Big ecosystem | Достъп до Nim + C ecosystem |