Учебник Clojure для начинающих
Clojure — современный диалект Lisp, работающий на JVM. Это функциональный язык, построенный вокруг неизменяемых данных, простоты и интерактивной разработки в REPL. В этом курсе вы пройдёте путь от страха перед скобками до уверенного Lisp-мышления: научитесь читать и писать s-выражения, работать с персистентными структурами данных, управлять состоянием через atom/ref/agent, ленить вычисления, использовать мультиметоды и протоколы, а в финале — писать собственные макросы, расширяя сам язык. Курс рассчитан на тех, кто уже знаком с программированием (особенно полезен опыт Java, Haskell, Scala или Elixir) и хочет понять, почему Clojure любят за надёжность и продуктивность.
Курс «Clojure: современный Lisp на JVM» состоит из 6 разделов и 19 уроков: Знакомство с Clojure, Синтаксис Lisp и s-выражения, Неизменяемые структуры данных, Функции и функциональный стиль, Состояние, ленивость и данные и Полиморфизм, макросы и экосистема. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Знакомство с Clojure
- Что такое Clojure и зачем он нужен
Clojure — современный Lisp на JVM: функциональный язык для конкурентности и работы с данными, философия простоты Рича Хикки.
- Философия простоты Рича Хикки
Simple Made Easy: чем «простое» отличается от «лёгкого», почему Clojure разделяет состояние, время и значение, и зачем это нужно.
- Установка, Leiningen, deps.edn и первый REPL
Как поставить Clojure: JVM, Leiningen и deps.edn, чем они отличаются, как запустить REPL и почему интерактивная разработка — ядро культуры.
- Что такое Clojure и зачем он нужен
2 Синтаксис Lisp и s-выражения
- S-выражения и префиксная запись
Как устроены s-выражения в Clojure: всё — списки, оператор стоит первым, почему префиксная запись единообразна и удобна.
- Ключевые слова и символы
Чем ключевое слово (:name) отличается от символа (name) в Clojure, зачем нужны keyword-ключи в map и как они ускоряют поиск.
- Код как данные и гомоиконность
Почему в Lisp код — это данные: цитирование через quote, программа как список, и как гомоиконность открывает дорогу к макросам.
- S-выражения и префиксная запись
3 Неизменяемые структуры данных
- Списки, векторы, map и множества
Четыре главные коллекции Clojure: список, вектор, отображение (map) и множество — когда какую использовать и базовые операции.
- Персистентность и структурное разделение
Как неизменяемые коллекции Clojure остаются быстрыми: персистентные структуры данных и структурное разделение (structural sharing) без копирования.
- Деструктуризация
Деструктуризация в Clojure: разбор векторов и map прямо в let и параметрах функций, ключи :keys, :as и значения по умолчанию :or.
- Списки, векторы, map и множества
4 Функции и функциональный стиль
- defn, анонимные fn и форма #()
Определение функций в Clojure: defn с именем, анонимная fn, краткая форма #() с %, и функции с несколькими арностями.
- Функции высшего порядка: map, filter, reduce
Три кита обработки данных в Clojure: map преобразует, filter отбирает, reduce сворачивает коллекцию в одно значение.
- Трединг-макросы -> и ->>
Трединг-макросы Clojure -> и ->>: как развернуть глубоко вложенные вызовы в читаемую цепочку преобразований данных.
- defn, анонимные fn и форма #()
5 Состояние, ленивость и данные
- Управление состоянием: atom, ref, agent и STM
Как Clojure управляет изменяемым состоянием безопасно: atom для независимого состояния, ref и STM для согласованных изменений, agent для асинхронных.
- Ленивые и бесконечные последовательности
Ленивые последовательности в Clojure: вычисление по запросу, бесконечные последовательности через range/iterate/repeat и взятие нужной части через take.
- Данные как данные: EDN, get-in и update-in
Формат EDN и работа с вложенными структурами в Clojure: чтение/запись данных, доступ через get-in и неизменяемое обновление через update-in и assoc-in.
- Управление состоянием: atom, ref, agent и STM
6 Полиморфизм, макросы и экосистема
- Полиморфизм: мультиметоды и протоколы
Два способа полиморфизма в Clojure: мультиметоды с диспетчеризацией по любому признаку и протоколы как быстрые наборы методов по типу.
- Макросы и метапрограммирование
Макросы Clojure: код как данные, defmacro, цитирование и шаблоны, как создать собственный синтаксис — суперсила Lisp и метапрограммирование.
- Взаимодействие с Java и обзор ClojureScript
Clojure и JVM: вызов Java-библиотек через interop-синтаксис, создание объектов и статические методы, а также обзор ClojureScript — Clojure в браузере.
- Конкурентность core.async и место Clojure среди ФП
Обзор core.async и каналов в Clojure для конкурентности, а также сравнение Clojure с Haskell и Scala: почему Lisp, неизменяемость и где применяют язык.
- Полиморфизм: мультиметоды и протоколы