Какое преимущество имеют обычные макросы для читателей LISP, которых нет у Clojure?
Я недавно использовал Clojure, но до сих пор не понимаю, какую функциональность я не получаю, которую предоставляют обычные макросы для читателей lisp. Можете объяснить, объясните мне это простыми словами?
3 ответа
Короче говоря, макросы читателей дают вам возможность переопределить синтаксис языка программирования в некотором ограниченном контексте.
Например, вы можете реализовать литералы регулярных выражений (например, #"pattern"
) сами дали читателю макросы. Без них вы были бы вынуждены корректно экранировать регулярные выражения в строковых литералах, передаваемых re-pattern
,
Кстати, в то время как нет общедоступных API Clojure для модификации читателя, это не невозможно, как показано в этих постах:
Простой пример Common Lisp имеет другой синтаксис читателя для векторов #() вместо []. Но с возможностью создания пользовательских макросов для чтения вы можете иметь макрос для чтения, который также транслирует [2 3 4 5] в вектор в Common Lisp.
Поскольку большинство пользователей не будут знать о значении созданных ими макросов для чтения, они используются редко, и чтобы избежать путаницы, Рич Хикки решил исключить возможность использования пользовательских макросов для чтения в Clojure. Однако в Clojure есть предопределенные макросы читателя - кавычка, вектор, регулярное выражение, карта и т. Д.
В Common Lisp читатель расширяется пользователем с помощью макросов читателя. Читатель несет ответственность за чтение s-выражений. S-выражения - это внешний текстовый синтаксис для типов данных Lisp, таких как числа, строки, символы, списки, выражения, структуры, массивы, символы,...
Читатель не несет ответственности за синтаксис языка программирования Lisp - только за s-выражения.
Таким образом, основная цель, с точки зрения пользователя, для макросов читателя - расширить или изменить синтаксис s-выражений. Например, пользователь может добавить текстовый синтаксис для различных классов CLOS (например, URL, ...), хеш-таблиц, специальных идентификаторов, новых типов чисел,...
Иногда он также используется для встраивания синтаксиса других языков / синтаксиса, которые имеют разные правила для формирования токенов: встроенный SQL, встроенный C, выражения инфикса, встроенные вызовы Objective C, встроенные языки правил, встроенный XML, встроенный JSON и многое другое.
Другое использование - предоставить пользователю дополнительный контроль над s-выражениями, которые фактически читает читатель. Например, условные выражения функций.
Таким образом, программируемые пользователем макросы считывателя позволяют пользователю настраивать считыватель с учетом вышеописанных функциональных возможностей. Можно предположить, что это полезно для тех пользователей, которые хотят настроить язык на уровне синтаксиса данных / токенов, но добавляет еще один уровень сложности.