Краткий экскурс в синтаксис Clojure, который настолько лаконичен, что вы сможете прочитать этот раздел примерно за 15 минут (или меньше). ;; две точки с запятой для комментария строки, ; одна точка с запятой для комментария остальной части строки. #_ макрос чтения комментариев, чтобы закомментировать следующую форму. (comment ) форма для комментариев ко всем содержащимся формам. Clojure написан в "формах", которые представляют собой списки элементов, заключенных в круглые скобки () и разделенных пробелами. Clojure считает первое значение в форме вызовом функции. Дополнительные значения в форме передаются в качестве аргументов вызываемой функции. Clojure организован в виде одного или нескольких пространств имен. Пространство имен представляет собой путь к каталогу и имя файла, который содержит код конкретного пространства имен. Функция str создает новую строку из всех переданных аргументов. clojure.string возвращает строковые значения (другие функции возвращают символы в качестве результата). Функции используют префиксную нотацию, поэтому вы можете легко выполнять математические вычисления с несколькими значениями. Математический метод очень точен, нет необходимости в правилах предшествования операторов (так как операторов нет). Благодаря вложенным формам вычисления очень точны. Равенство — это = ; вам нужно использовать в логике not, так  (not true) ; => false Clojure имеет строгую типизацию, поэтому в Clojure все является типом. Clojure является динамически типизированным, поэтому сам определяет тип. Тип не нужно указывать в коде, что делает код более простым и лаконичным. Поскольку Clojure является размещаемым на уже существующей платформе языком, он использует систему типов используемой среды, где это уместно. Например, Clojure под капотом применяет объектные типы Java для булевых данных, строк и чисел. Для проверки типа кода в Clojure используйте функции class или type. Vectors (векторы) и Lists (списки) — это тоже классы java! Наиболее распространенные коллекции данных в Clojure: (1 2 "three") или (list 1 2 "three") — список значений, прочитанный от начала до конца (последовательный доступ).  или (list 1 2 "three") — вектор значений с индексом (произвольный доступ). {:key "value"} или (hash-map :key "value") — хэштаблица (хэшмапа) с нулем или более пар ключ-значение (ассоциативная связь). #{1 2 "three"} или (set 1 2 "three") — уникальный набор значений. Список () определяется как вызов функции. Первый элемент списка — имя вызываемой функции, а дополнительные значения являются аргументами функции. Функция ' quote сообщает читателю Clojure, что список следует рассматривать только как данные. Списки и векторы — это коллекции. Только списки являются последовательностями. Последовательности — это интерфейс для логических списков, которые могут быть ленивыми. "Ленивая" означает, что последовательность значений не оценивается до тех пор, пока к ней не обратятся. Ленивая последовательность позволяет использовать большие или даже бесконечные серии, например, как: Используйте cons для добавления элемента в начало списка или вектора. Используйте conj, чтобы добавить элемент относительно типа коллекции, в начало списка или в конец вектора. Используйте concat для сложения списков или векторов вместе. Используйте filter, map для взаимодействия с коллекциями. Используйте reduce для их уменьшения. Reduce также может принимать аргумент начального значения. Эквивалент (conj (conj (conj (conj [] 3) 2) 1) Используйте fn для создания новых функций, определяющих какое-то поведение. fn называют анонимной функцией, поскольку она не имеет внешнего имени, на которое можно сослаться, и ее нужно вызывать в форме списка. Оберните форму (fn ,,,) в круглые скобки, чтобы вызвать ее и вернуть результат. Создайте многократно используемую функцию с помощью def, создав имя, которым будет var. Поведение функции, определенное в def, может быть изменено, а выражение переоценено для использования нового поведения. [] — это список аргументов для функции. Clojure поддерживает мультивариадические функции, позволяя одному определению функции отвечать на вызов функции с разным количеством аргументов. Функции могут упаковывать дополнительные аргументы в последовательность. Вы можете смешивать обычные и упакованные аргументы. Ключевые слова подобны строкам с небольшим бонусом в плане эффективности. Мапы могут использовать любой тип в качестве ключа, но как правило, лучше всего подходят ключевые слова. Запятые — это пробелы. Запятые всегда рассматриваются как пробелы и игнорируются Clojure-ридером. Получение значения из мапы путем вызова ее как функции. Ключевые слова позволяют извлекать их значение из мапы. Строки так не используются. При извлечении значения, которое не было представлено, возвращается nil. Используйте assoc для добавления новых ключей в хэшмапы. Но помните, что типы clojure иммутабельны! Используйте dissoc для удаления ключей. Добавьте элемент с помощью conj. Удалите его с помощью disj. В пространстве имен clojure.sets есть больше функций. Логические конструкции в clojure — это просто макросы, и выглядят они так же, как и все остальное. Используйте let для создания временных привязок. Группируйте утверждения вместе с помощью do. Функции имеют неявный do. Так же как и let. Пространства имен используются для того, чтобы организовать код в логические группы. В верхней части каждого файла Clojure есть форма ns, которая определяет название пространства имен. Доменная часть названия пространства имен обычно является наименованием организации или сообщества (например, GitHub user/organisation). Все проекты Practicalli имеют домены пространства имен practicalli require позволяет коду из одного пространства имен быть доступным из другого пространства имен, либо из того же проекта Clojure, либо из библиотеки, добавленной в classpath (путь к классам) проекта. Директива :as в require используется для указания имени псевдонима, которое сокращенно обозначает полное имя библиотеки. Или :refer [function-name var-name] может использоваться для указания конкретных функций и данных (vars), которые доступны напрямую. Требуемая (required) директива обычно добавляется к форме пространства имен. Функции из clojure.set можно использовать через псевдоним, а не через полное имя, т.е. clojure.set/intersection Директива :require может быть использована для включения нескольких пространств имен библиотек. require может использоваться самостоятельно, обычно в блоке многофункционального кода. В Java есть огромная и полезная стандартная библиотека, поэтому вы захотите узнать, как с ней работать. Используйте import для загрузки пакета java. Или импорт из имени пакета java. Используйте имя класса с символом "." в конце, чтобы создать новый экземпляр. Используйте . для вызова методов. Или используйте горячую клавишу ".method". Используйте / для вызова статических методов. Используйте doto, чтобы сделать ощущения от взаимодействия с (мутабельными [изменяемыми]) классами более толерантными. Язык программирования Clojure — это язык программирования общего назначения, на нём можно разрабатывать абсолютно что угодно. Но до недавнего времени разработка скриптов на Clojure была довольно трудной задачей, в основном, из-за медленного старта JVM. Появление GraalVM позволило обойти это ограничение. Скрипты, написанные на Clojure, стартуют практически мгновенно. При этом в процессе разработки доступен REPL и весь арсенал языка Clojure. На бесплатном вебинаре вы познакомитесь с проектом Babashka и узнаете, как именно эта библиотека помогает разрабатывать скрипты. Приглашаем всех желающих.  Записаться на открытый урок можно на странице "Clojure Developer".  Редактор