Emacs lisp определяет синтаксис
Вопрос
Есть ли в этом какие-либо аналогии со схемой define-syntax
в ELisp?В define-syntax
Я могу указать некоторые ключевые слова и в elisp defmacro
кажется, я не могу.РЕДАКТИРОВАТЬ:Кажется, я либо плохо вас понимаю, либо мой вопрос неясен.В схеме можно определить макрос с зарезервированными словами типа
(петля
for
ain
какой-то список(петля
while
…
В Emacs Lisp я не нашел способа ввести такой сахар.Самое большее, что я могу сделать для макроса, который должен вызываться следующим образом
(цикл - для списка (делать - много чего...)
Удобочитаемость имеет значение
Решение
Как Scheme, так и Elisp имеют макросистемы."Ключевые слова" define-syntax
и defmacro
оба вводят имя для определенного пользователем макроса.
В то время, когда макрос foo используется в реальном коде, скажем (foo 1 bar)
расширитель макроса должен определить, как переписать заданную форму, (foo 1 bar)
, в более простую форму , не содержащую пользовательских макросов.Расширитель макроса вызывает функцию, которая была определена во время создания макроса foo
был определен.Т.е.он вызывает функцию, которую вы указали с помощью define-syntax
или defmacro
с представлением формы, (foo 1 bar)
.Представление может быть в виде "синтаксических объектов" или простых списков (это отличается в разных макросистемах).
Это мой взгляд на сходство между define-syntax
и defmacro
.
Однако макросистемы схемы R5RS и Elisp отличаются друг от друга.
Расширитель макросов, связанный с foo
может ли схема R5RS быть задана с помощью syntax-rules
.Это позволяет вам использовать сопоставление с образцом для указания правил перезаписи (внутренне форма синтаксических правил будет оцениваться как функционирующая).Другие отличия:Алгоритм расширения макроса в схеме R5RS поможет вам снова непреднамеренно ввести имена, конфликтующие с именами из других частей вашей программы (скажем, из библиотеки, которую вы написали не сами).Исторически сложилось так
Из-за того, как пространства имен работают в Lisp, эта проблема в Lisp не такая уж большая, но ошибки допускать можно.
Исторически Scheme и Elisp использовали один и тот же алгоритм макрорасширения, но затем разработчики схем начали экспериментировать с другими алгоритмами.Система "синтаксических правил" была введена в R5RS, но эволюция на этом не остановилась.В наши дни все современные реализации схем имеют (варианты) систему "синтаксис-регистр".
Некоторые реализации проделали работу, чтобы заставить этот алгоритм расширения работать с модулями (Racket, R6RS-реализации и другие).
Короче говоря, когда вы читаете о макросистемах Scheme, внимательно изучите, о каком именно варианте вы читаете.Если вы читаете об ограничениях, то, скорее всего, вы нашли текст на (теперь уже довольно старом) syntax-rules
система.