Данные == код

Данные — это код

Обычно в синтаксисе языка программирования присутствуют конструкции, отвечающие за описание значений встроенных типов. Такие конструкции называют литералами. Так числовые литералы описывают числа, а строковые — строки. Часто, если в языке есть встроенные структуры данных, в синтаксисе этого языка присутствуют и литералы для описания значений соответствующих типов. В JavaScript литералы объектов и массивов описывают объекты и массивы соответственно.

Поскольку литералы являются частью синтаксиса языка, то можно сказать, что любые описанные с помощью литералов данные — это код.

Однако, практически всегда синтаксис литералов является лишь небольшой частью синтаксиса всего языка. Вы просто не сможете описать, скажем, массив ключевых слов языка или добавить новый оператор в тело цикла: ключевые слова и управляющие инструкции не являются данными, доступными самому языку для манипулирования.

Иногда тот или иной язык предоставляет специальные средства для манипулирования собственным кодом — так называемые средства метапрограммирования. Но даже если язык и поддерживает метапрограммирование, то обычно манипулирование синтаксисом и манипулирование "обычными" данными — разные виде деятельности. И фаза манипулирования кодом, как правило, отделена от фазы его выполнения: сначала весь код приводится к окончательному виду, и только потом исполняется (возможно, предварительно компилируется).

Код — это данные

В лиспоподобных языках для записи кода используются те же литералы, которые описывают данные. В классических лиспах вообще используется преимущественно одна структура данных — список. Любая программа состоит из списков и манипулирует списками же, а значит она может манипулировать собственным кодом. Получается, что в таких языках любой код — это данные!

Такое свойство языка, заключающееся в том, что и код и данные описываются одинаковым образом, называется гомоиконичностью (homoiconicity). При этом не важно, используется ли для описания любых значений одна структура данных или несколько. Важно лишь то, что любой код можно использовать ещё и как сложносоставное значение, которое можно преобразовывать силами языка и затем исполнять.

Код на Clojure и EDN

Clojure — язык гомоиконичный. Подобно другим лиспам, язык использует списковые литералы для описания кода, но добавляет к ним ещё несколько структур, чтобы людям было проще этот код читать.

Кроме общего синтаксиса Clojure ещё существует его подмножество, называемое EDNExtensible Data Notation. Это такой формат представления данных, который позволяет описать любые, понятные Clojure данные, но при этом не завязан именно на язык программирования. Можно сказать, что EDN относится к Clojure, как JSON относится к JavaScript — оба формата удобны для хранения и передачи данных, но могут быть и без каких-либо преобразований вставлены в код на соответствующем языке, где станут работать как литералы.

Поскольку код на Clojure практически полностью состоит из EDN, стоит начать знакомиться с синтаксисом EDN, а потом плавно перейти к специфичным именно для Clojure вещам.