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

История языка 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.