Перейти к основному содержимому

История языка Clojure

Разработчику

Черновик статьи. Ниже — развёрнутая хронология, идеи дизайна и контекст экосистемы; отдельные главы по ClojureScript и Datomic дополнятся позже.


Краткая хронология​

ГодСобытие
2003–2006Rich Hickey разрабатывает Clojure в частном порядке
2007Публичный релиз Clojure 1.0
2009Рост сообщества, появление Leiningen
2010ClojureScript — компиляция в JavaScript
2011Datomic — база данных от Rich Hickey
2013tools.deps / deps.edn как альтернатива Leiningen
2014–2018spec, core.async, transducers в core
2019+Clojure 1.10–1.12, улучшения error messages
2020sИнтеграция с Java 17+, GraalVM native-image для CLI

Rich Hickey до Clojure работал над системами в C++, Java и C# — опыт подсказал, что сложность состояния (mutable shared state) дороже, чем кажется на старте проекта.


Мотивация Rich Hickey​

Доклады Simple Made Easy (2011) и The Value of Values (2012) сформулировали философию языка:

  • Простота (simple) — объект с малым числом переплетений; лёгкость (easy) — близость к привычному, не всегда простое.
  • Неизменяемые значения упрощают reasoning в многопоточности и распределённых системах.
  • Время явно: identity имеет state, которое меняется через controlled механизмы (atom, ref), а не скрытые мутации полей.

Clojure создавался как ответ на enterprise Java с наследованием, ORM-магией и implicit mutable state — при сохранении доступа к JVM-библиотекам.


Идеи дизайна​

Immutable data structures​

Persistent collections (vector, map, set) structurally sharing память при conj, assoc, dissoc. Старые версии данных остаются валидными для читателей — важно для concurrency и event sourcing.

(def v1 [1 2 3])
(def v2 (conj v1 4))
; v1 по-прежнему [1 2 3], v2 — [1 2 3 4]

Identity и state​

МеханизмКогда использовать
atomОдиночное значение, swap!
refКоординированные изменения в STM
agentAsync update с callback
varDynamic binding per thread

ОО-модель "объект = state + identity" заменена явным разделением.

Lisp macros​

Макросы трансформируют AST на этапе компиляции — язык расширяется без изменения компилятора. Примеры в core: ->, ->>, defn, when-let.

Java interop​

Clojure компилируется в JVM bytecode. Вызов Java:

(java.util.UUID/randomUUID)

Interop без генерации stub-классов — любой JAR из Maven Central.

Композиция вместо наследования​

Поведение собирают из функций над map/vector, protocols и multimethods — не от deep class hierarchies.


Связь с другими языками​

ЯзыкСвязь
Common LispS-expressions, macros, REPL culture
SchemeМинимализм (Clojure сознательно богаче core)
JavaRuntime, библиотеки, hiring
ScalaJVM, FP (иной синтаксис, статическая типизация)
HaskellImmutability, laziness (Clojure — eager по умолчанию)
ErlangИдеи identity/state (Rich изучал actor model)

Clojure не pure FP: def, atoms и host interop допускают imperative стиль там, где это оправдано.


Эволюция tooling​

Leiningen (2009+)​

Долгое время стандарт: lein new, lein repl, lein uberjar. project.clj — аналог build.gradle с декларативными deps.

tools.deps и Clojure CLI (2018+)​

deps.edn — EDN-файл зависимостей; команды clojure -M, clojure -X, clojure -A для alias. Официальный путь для новых проектов.

nREPL и IDE​

nREPL — сетевой протокол REPL; Calva (VS Code), Cursive (IntelliJ), Emacs CIDER подключаются к running process для eval buffer.


ClojureScript и фронтенд​

ClojureScript (2010) — тот же синтаксис, другой host (JS engine). Компилятор генерирует JS; популярны:

  • Reagent — React wrapper;
  • re-frame — архитектура SPA на events/subscriptions;
  • Shadow-cljs — сборка и hot reload.

Fullstack-команда может шарить clojure.spec или схемы данных между backend и frontend.


Datomic и data-oriented design​

Datomic (2012) — immutable database-as-a-value, queries на Datalog, время как first-class dimension. Идеи перекликаются с immutability в языке — append-only facts, не update-in-place rows.

Не обязательна для изучения Clojure, но показывает, куда ведёт data-centric мышление автора.


Сообщество и применение​

ОбластьПримеры
FintechСистемы с высокими требованиями к корректности
DataETL, streaming (Onyx, перешёл в open source heritage)
Dev toolsMetabase (частично Clojure stack)
Open sourcePenpot ecosystem, библиотеки data transformation

Вакансии меньше, чем Java, но стабильный niche; ценятся опыт JVM + функциональное мышление.


Clojure сегодня​

Актуальная ветка — Clojure 1.12+ на Java 8+ (рекомендуется Temurin 17 или 21). Язык в maintenance + evolution режиме: обратная совместимость сильная, breaking changes редки.

Соседние темы для углубления:


Что дополнится в следующих версиях статьи​

  • Детальная таблица релизов 1.0–1.12 с ключевыми фичами.
  • Clojure CLR и Babashka (native scripting).
  • Сравнение hiring и learning curve с Kotlin/Scala.
  • Кейсы миграции Java → Clojure модуль за модулем.
Черновик

Доклады Rich Hickey на InfoQ и Strange Loop — лучший первичный источник мотивации языка. Видео Simple Made Easy стоит посмотреть до глубокого погружения в syntax.

Дальше по разделу: первая программа · о разделе.


Второй проход — доклады и open source (черновик)​

Первичные источники Rich Hickey​

ДокладТема
Simple Made EasyПростота и удобство
The Value of ValuesImmutability
Hammock Driven DevelopmentREPL и обдумывание

Видео на InfoQ и YouTube — смотреть до углубления в syntax; философия объясняет atoms и Datomic.

Заметные open source проекты​

ПроектСтек
MetabaseClojure backend, BI
PenpotClojureScript + backend
clojure.core.asyncCSP channels

Вакансии с Clojure часто упоминают data-oriented backend и REPL-driven development.

Сравнение hiring: JVM языки​

ЯзыкЧастота вакансийТипичный контекст
Java/KotlinВысокаяEnterprise, Android
ScalaСредняяData, финтех
ClojureНишеваяСтартапы, analytics

Clojure не цель для максимального найма — цель для JVM + FP без корпоративного boilerplate.


Rich Hickey — ключевые доклады​

ДокладТема
Simple Made EasyПростота vs привычность
The Value of ValuesImmutability и время
Hammock Driven DevREPL и глубокое мышление
Clojure, The Art of AbstractionData vs objects

Доклады доступны на InfoQ и YouTube — полезны до синтаксиса.


Версии Clojure 1.x (выборка)​

ВерсияФича
1.7Transducers
1.8String functions, additional Java 8 interop
1.9Spec alpha
1.10Error messages, tap
1.11Syntax improvements
1.12continue evolution, JDK 17+ focus

Обратная совместимость — сильная сторона; код 2015 часто работает на 1.12 с минимальными правками.


Clojure в индустрии (примеры)​

Компания / проектОбласть
Nubank (исторически)Fintech, масштаб
MetabaseAnalytics OSS
PitchPresentation software
Roam Research (частично)Knowledge graph

Список иллюстративный — проверяйте актуальность стека перед интервью.


От Lisp к Clojure​

Common Lisp и Scheme дали:

  • homoiconicity (код = данные);
  • macro system;
  • REPL culture.

Clojure отбросил mutable state OO, CLOS-style ОО и legacy syntax — pragmatic FP на JVM.


Babashka и scripting (2020+)​

Babashka — native Clojure interpreter на GraalVM для быстрых CLI-скриптов без JVM cold start:

bb -e '(println (+ 1 2))'

Подходит для CI tasks, замены bash glue с доступом к Clojure stdlib. Не заменяет полноценный JVM backend с hot reload nREPL.


Clojure CLR (кратко)​

ClojureCLR — порт на .NET CLR. Niche; основной путь — JVM + ClojureScript. Упоминается для команд с mixed .NET/Java инфраструктурой.


Spec, Malli и контракты​

После clojure.spec (1.9) сообщество добавило Malli, Schema — валидация на границах API. Идея Rich Hickey: runtime checks + generative tests вместо тяжёлой статической системы типов.


GraalVM native-image​

Компиляция uberjar в native binary уменьшает startup time для serverless и CLI. Trade-off: reflection config, longer build. Актуально для Clojure 1.11+ и Java 17.


Хронология для запоминания​

2007 Clojure 1.0 → 2010 ClojureScript → 2012 Datomic → 2018 deps.edn → 2020s Babashka

Чек-лист после истории​

  • Понятна разница identity/state/value
  • Названы atom, ref, agent
  • Объяснено, зачем JVM host
  • Прочитан план первой программы

Дальше: первая программа · о разделе.


Доклады Rich Hickey (что смотреть)​

ДокладТема
Simple Made EasyПростота vs привычность
The Value of ValuesImmutability
Hammock Driven DevREPL и thinking time

Видео на InfoQ — контекст перед синтаксисом.


Сравнение hiring: Clojure, Kotlin, Scala​

ClojureKotlinScala
JVM jobsNicheAndroid + backendEnterprise + data
FPCoreOptionalHybrid
SyntaxLispJava-likeScala

Clojure — сознательный выбор data-oriented команд, не mass market.


Упражнения​

  1. Timeline 2007–2025 на одной странице.
  2. Объясните atom vs ref своими словами.
  3. Найдите Metabase или Penpot Clojure usage.
  4. Сравните conj на vector и list.
  5. Прочитайте Simple Made Easy summary.
  6. Связь с Erlang/Elixir actors.
  7. Babashka one-liner bb -e '(+ 1 2)'.
  8. Почему no nil punning in Clojure maps?
  9. Java interop example без wrapper generation.
  10. Next: 7.md REPL practice.

FAQ​

Rich Hickey still active? Clojure evolution continues; Datomic separate company.

Clojure 1.12 features? Better errors, continued host interop.

Why no classes? Protocols, records, multimethods instead.

ClojureScript same language? Same semantics, different host.

Learning curve? Parentheses + immutability; Java libs help.

IDE mandatory? REPL enough; Calva improves UX.

Breaking legacy? Strong backward compatibility culture.

Open source examples? Metabase, re-frame apps on GitHub.

Next after history? 7.md, intro.md.

Community Slack/Discord? Clojurians Slack — основной чат сообщества.


Rich Hickey до Clojure​

До языка Hickey работал над системами на C++, Java, C#, Perl — опыт показал, что скрытое shared mutable state дороже, чем кажется. Clojure — ответ на complexity of state, не на нехватку скобок.


Clojure и Elixir (концептуально)​

ИдеяClojureElixir
ImmutabilityPersistent collectionsImmutable data
ConcurrencySTM, core.asyncOTP actors
HostJVMBEAM

Параллельное чтение: Elixir intro.


Упражнения (история)​

  1. Timeline на одной странице 2007–2025.
  2. Три тезиса из Simple Made Easy.
  3. Пример Java interop без wrapper.
  4. Сравните atom и ref одним предложением каждый.
  5. Найдите open source проект на Clojure на GitHub.