раздел 28
Clojure
Clojure учит мыслить данными, а не объектами. Сначала база: REPL как способ работы, литералы, четыре коллекции и мапы вместо классов, деструктуризация, абстракция последовательности. Дальше функциональное ядро: функции и комбинаторы, ленивые последовательности, библиотека из десятков функций над данными, потоковые макросы, loop и recur. Состояние отдельно от значений: атом, ref и транзакционная память, агенты и future. Полиморфизм без наследования через мультиметоды и протоколы, макросы и их гигиена, EDN и схемы spec и malli на границе системы. Финал прикладной: интероп с хостом, core.async, babashka и тесты, HTTP-сервис на Ring, трансдьюсеры и разбор лога событий игры одним проходом. Живые сниппеты работают прямо в браузере на SCI.
Не получилось изменить список. Попробуй ещё раз.
Раздел открыт для всех. Войди, чтобы отмечать пройденные уроки, вести заметки и решать задачи в редакторе. войти
Уроки раздела
- Зачем Clojure
- REPL как способ работы
- Формы и литералы
- Четыре коллекции
- Мапы как сущности
- Персистентность изнутри
- Деструктуризация
- Абстракция последовательности
- Функции: fn, арность, замыкания, partial и comp
- Ленивые последовательности: range, iterate, lazy-seq и чанки
- Библиотека последовательностей: map, filter, reduce и ещё три десятка
- Потоковые макросы: ->, ->>, some->, cond-> и as->
- Рекурсия: loop, recur и почему нет хвостовых вызовов
- Значения и идентичность: модель времени Хики
- Атом: swap!, reset!, валидаторы и наблюдатели
- Ref и STM: координированные изменения
- Агенты, future, promise и delay
- Мультиметоды и иерархии: правила боя
- Протоколы и записи
- Когда что: мапа, запись, протокол, мультиметод
- Код как данные
- Гигиена макросов
- DSL квестов: макрос и данные
- EDN и данные на границе
- Схемы: spec и malli
- Интероп с хостом: JVM и JavaScript
- core.async: каналы и go-блоки
- Babashka, ClojureScript и тесты
- HTTP-сервис на Ring
- Трансдьюсеры: преобразование без промежуточных коллекций
- Алгопрактика на Clojure
- Сквозной проект: разбор events.log
Понятия курса
Понятия разобраны внутри уроков. Нажми на понятие, чтобы открыть урок, где оно объясняется.
Старт
- Зачем ClojureЛисп на чужом рантайме: JVM, JavaScript, babashka. Ставка на неизменяемые данные, функции поверх мап и состояние с явной семантикой.урок 1 · Зачем Clojureопираются: урок 2
- Формы и литералыЧисла, строки, символы, ключевые слова, nil и истинность. Вызов это список, скобки читаются как дерево.урок 3 · Формы и литералыопираются: урок 4
- REPL как способ работыclj и deps.edn, редактор, подключённый к REPL, вычисление формы под курсором. Программа растёт в живом процессе.урок 2 · REPL как способ работыопираются: урок 3
Данные
- ДеструктуризацияРазбор векторов и мап прямо в let и в аргументах: позиции, :keys, :or, :as, вложенный разбор и & для хвоста.урок 7 · Деструктуризацияопираются: урок 9
- Мапы как сущностиГерой игры это мапа с ключевыми словами. get-in, assoc-in, update-in и update меняют вложенные данные, не трогая исходник.урок 5 · Мапы как сущностиопираются: урок 7, урок 24
- Четыре коллекцииСписок, вектор, мапа, множество. conj кладёт туда, где дешевле, get, contains? и count работают со всеми.урок 4 · Четыре коллекцииопираются: урок 5, урок 6, урок 8
- Абстракция последовательностиseq, first, rest, cons, next: один интерфейс над любой коллекцией. Мапа как последовательность пар, строка как последовательность символов.урок 8 · Абстракция последовательностиопираются: урок 10
- Персистентность изнутриВектор это дерево с ветвлением 32: новая версия копирует путь до листа, остальное общее. Отсюда O(log₃₂ n) и дешёвые снимки.урок 6 · Персистентность изнутриопираются: урок 14
Функциональное ядро
- Потоковые макросы-> подставляет значение первым аргументом, ->> последним. some-> останавливается на nil, cond-> применяет шаги по условию, as-> даёт имя.урок 12 · Потоковые макросы: ->, ->>, some->, cond-> и as->опираются: урок 21
- Функцииdefn, fn и #(), несколько арностей, вариадические аргументы, замыкания. partial, comp, juxt и apply собирают функции из функций.урок 9 · Функции: fn, арность, замыкания, partial и compопираются: урок 11, урок 12, урок 13, урок 18
- Библиотека последовательностейmap, filter, reduce и ещё три десятка функций: group-by, frequencies, partition, sort-by, keep, mapcat. Как найти нужную по задаче.урок 11 · Библиотека последовательностей: map, filter, reduce и ещё три десяткаопираются: урок 30, урок 31
- Ленивые последовательностиrange, iterate, repeat и cycle без конца, take отрезает нужное. lazy-seq своими руками, чанки по 32 и ловушка побочных эффектов внутри map.урок 10 · Ленивые последовательности: range, iterate, lazy-seq и чанкиопираются: урок 11
- Рекурсия: loop и recurХвостовых вызовов на JVM нет, поэтому recur: явный прыжок в начало loop или функции. trampoline для взаимной рекурсии.урок 13 · Рекурсия: loop, recur и почему нет хвостовых вызововопираются: урок 31
Состояние
- АтомМир игры в одном атоме: swap! применяет чистую функцию к текущему значению, reset! кладёт новое. Валидатор и наблюдатели.урок 15 · Атом: swap!, reset!, валидаторы и наблюдателиопираются: урок 16, урок 29
- Значения и идентичностьМодель времени Хики: значение не меняется никогда, идентичность это ссылка, которая в разные моменты указывает на разные значения.урок 14 · Значения и идентичность: модель времени Хикиопираются: урок 15
- Агенты, future, promise, delayАгент меняет состояние асинхронно и по очереди. future считает в другом потоке, promise ждёт значения, delay вычисляет один раз.урок 17 · Агенты, future, promise и delayопираются: урок 27
- Ref и STMКогда меняются две ссылки сразу: dosync, alter, commute и ensure. Транзакция повторяется при конфликте, побочные эффекты внутри запрещены.урок 16 · Ref и STM: координированные измененияопираются: урок 17
Полиморфизм
- Когда что: мапа, запись, протокол, мультиметодНачинай с мапы и функции. Запись, когда поля известны и нужна скорость, протокол для набора операций над типами, мультиметод для диспетчеризации по данным.урок 20 · Когда что: мапа, запись, протокол, мультиметод
- Мультиметоды и иерархииdefmulti с функцией диспетчеризации по любым данным, defmethod на каждое значение. derive строит иерархию ключевых слов без классов.урок 18 · Мультиметоды и иерархии: правила бояопираются: урок 19
- Протоколы и записиdefprotocol описывает набор функций, defrecord и extend-protocol дают реализации. Быстрая диспетчеризация по типу первого аргумента.урок 19 · Протоколы и записиопираются: урок 20, урок 26
Макросы
- Код как данныеПрограмма это списки и векторы, которые читает reader. quote останавливает вычисление, syntax-quote строит шаблон, macroexpand показывает подстановку.урок 21 · Код как данныеопираются: урок 22
- Гигиена макросовЗахват символов и двойное вычисление аргумента. gensym и авто-gensym x#, почему syntax-quote квалифицирует символы и как это спасает.урок 22 · Гигиена макросовопираются: урок 23
- DSL на макросах и на данныхЯзык квестов дважды: макросом defquest и простой мапой с интерпретатором. Первое правило макросов: не пиши макрос, если хватает данных.урок 23 · DSL квестов: макрос и данные
Данные как контракт
- Схемы: spec и malliДинамический язык и проверка формы данных на границе. clojure.spec: s/def, s/keys, s/valid?, explain, генераторы. malli: схема как данные.урок 25 · Схемы: spec и malli
- EDN и данные на границеEDN это литералы Clojure как формат обмена: мапы, векторы, множества, ключевые слова, теги #inst и #uuid. clojure.edn/read-string безопасен, read-string нет.урок 24 · EDN и данные на границеопираются: урок 25
Хост и экосистема
- Интероп с хостомClojure не прячет платформу: (.method obj), (Class/static), (new Class), import. Исключения хоста, try и ex-info, подсказки типов против рефлексии.урок 26 · Интероп с хостом: JVM и JavaScriptопираются: урок 28, урок 29
- Babashka, ClojureScript и тестыСкрипты на babashka вместо bash, ClojureScript в браузере, clojure.test: deftest, is, testing, are и фикстуры.урок 28 · Babashka, ClojureScript и тесты
- core.asyncКаналы и go-блоки в духе CSP: >!, <!, alts!, буферы и таймауты. go превращает код в машину состояний, поэтому блокирующий вызов внутри него вреден.урок 27 · core.async: каналы и go-блоки
Практика
- HTTP-сервис на RingОбработчик это функция от мапы запроса к мапе ответа, middleware это функция от обработчика к обработчику. Маршруты, JSON и тесты без сервера.урок 29 · HTTP-сервис на Ring
- Трансдьюсеры(map f) без коллекции это трансформация шага редукции. comp склеивает их в один проход без промежуточных последовательностей: transduce, into, sequence, eduction.урок 30 · Трансдьюсеры: преобразование без промежуточных коллекцийопираются: урок 32
Финал
- Алгопрактика на ClojureЗадачи с собеседований на неизменяемых структурах: частоты, два указателя без указателей, обход графа, динамика через reduce и мемоизацию.урок 31 · Алгопрактика на Clojure
- Сквозной проект: разбор лога событийevents.log «Хроник Пограничья» разбирается пайплайном на трансдьюсерах: воронка, топ событий, сессии. Ответ сверяется с цифрами курса аналитика.урок 32 · Сквозной проект: разбор events.log