Гомоиконичность


Гомоикони́чность (англ. homoiconicity, от греч. ὁμός — равный, одинаковый + «икони́чность» — отношение подобия между знаком и объектом, на который данный знак указывает (см. семиотика) — в свою очередь, от ср.-греч. εἰκόνα — «о́браз», «изображение») — свойство некоторых языков программирования, в которых структура программы похожа на его синтаксис, и поэтому внутреннее представление программы можно определить, прочитав текстовую разметку[1]. Если язык гомоикони́чен (англ. homoiconic), это означает, что текст программы имеет такую же структуру, как её абстрактное синтаксическое дерево (то есть AST и синтаксис являются изоморфными). Это позволяет всему коду на языке быть доступным и обработанным в качестве данных, используя одно и то же представление.

Примечание — В русскоязычной литературе из-за неосведомлённости о семиотике нередко используется неправильный вариант перевода «гомоиконность».

В гомоикони́чном языке первичное представление программ является также структурой данных в примитивном типе самого языка. Это делает метапрограммирование проще, чем на языке без этого свойства, поскольку код может рассматриваться как данные: рефлексия в языке (определение структуры программы во время выполнения) основана на единой, однородной структуре, и не нужно обрабатывать несколько различных конструкций, которые возникают в сложных синтаксических конструкциях. Говоря иначе, гомоиконичность — это когда исходный код программы пишется как базовая структура данных и язык программирования знает, как получить к ней доступ.

Типичным примером является язык программирования Лисп, который был создан, чтобы быть лёгким для списочных манипуляций, и где структура задана как S-выражения, которые принимают форму вложенных списков. Лисп-программы записываются в виде списков; в результате получается, что программа может получить доступ к своим собственным функциям во время работы, а также перепрограммировать себя «на лету». Гомоиконичные языки, как правило, включают полную поддержку синтаксических макросов, позволяющих программисту выражать программные преобразования в сжатой форме. Примерами таких языков программирования являются Clojure (современный диалект Лиспа), Rebol и Рефал.

Термин впервые упоминается в статье 1960 года Дага Макилроя[2], на которую в свою очередь сослались в работе 1965 года Кельвин Моурс[англ.] И Петер Дойч[англ.], в которой свойство представили как ключевое для разработанного ими языка программирования TRAC[англ.][3].

Алан Кэй использовал и, возможно, популяризировал термин «гомоиконичность», использовав его в кандидатской диссертации относительно соответствующих свойств Лиспа и языка TRAC[4], отметив при этом издержки удобочитаемости программ при таком подходе: «программы, написанные на них, выглядят как письмо короля Бурна-Буриаш к шумерам, напечатанном вавилонской клинописью».