LINUX.ORG.RU

[cl][макросы чтения] Вопрос по примеру из Let over lambda


0

1

В книге «Let over lambda» автор в качестве примера рассматривает создание макросов чтения, автоматически создающих из регулярных выражений лямбда-формы, вызывающие соответствующие функции из cl-ppcre. Я долго думал и так и не понял, зачем в этом примере было match-mode-ppcre-lambda-form и subst-mode-ppcre-lambda-form делать макросами (а не функциями) - ведь всё, что они делают - это генерируют код, который возвращает соответствующую лямбда-форму, при этом аргументы макроса вычисляются строго 1 раз (для этого используется описанный ранее в этой книге макрос defmacro!). Чем макрос в данном случае лучше функции, возвращающей нужную лямбда-форму (такую же, как выполнение раскрытия макроса) типа такой к примеру:

(defun match-mode-ppcre-lambda-form (args)
	   `(lambda (str)
	      (cl-ppcre:scan
	       ,(car args)
	       str)))

Может кто-нибудь прояснит ситуацию?

★★

Потому что объект функции нельзя дампнуть в fasl, например.

Ридер-макросы могут, конечно, возвращать все что угодно, но раскрываются то они соответствующих местах кода, а код, по-хорошему, должен представлять собой набор валидных для compile-file объектов.

Хотя, в то же время, в интерпретируемом коде(ну и вообще, если через load сразу сорцы загружать) таких ограничений нет. В контексте compile/eval ограничений нет также - в списках могут какие угодно объекты содержаться.

Love5an
()
Ответ на: комментарий от Love5an

Хотя, можно, конечно, определить какой-нибудь extended-function класс, через метаобъектный протокол, новые lambda и defun, и определить соответствующий make-load-form.

Love5an
()
Ответ на: комментарий от Love5an

> Потому что объект функции нельзя дампнуть в fasl, например.

А где там объект функции? Ридер-макрос (функция |#~-reader|) вызывается до компиляции (в процессе чтения), он, в свою очередь, вызывает match-mode-ppcre-lambda-form, которая возвращает _список_ (не объект функции!) (lambda (str) ...), который уже будет далее интерпретирован нужным образом в зависимости от места, в котором он употреблён. Приведённая выше функция возвращает точно такой же список (с точностью до имени переменной - аргумента лямбды) как и результат раскрытия макроса из LOL. В чём тогда принципиальная разница?

Если кратко: если в функции |#~-reader| заменить однимённый макрос на приведённую мной выше функцию, возвращаемое ею значение не изменится - проверял (изменится только имя переменной аргумента - был gensym, станет str. Но это не важно, т. к. никакого постороннего кода внутри оказаться не может; единственное возможное «нехорошее» последствие которое мне видится - str может переопределить одноимённую специальную переменную, которая (потенциально) может использоваться где-то в недрах cl-ppcre:scan, но при соблюдении стиля именования специальных переменных этим можно пренебречь...)

slav ★★
() автор топика
Ответ на: комментарий от slav

действительно, неправильно прочитал

хрен знает, нафиг там макрос
вообще, это плохой стиль, использовать макросы там, где можно функцией, тем более если это на производительности в рантайме не скажется

Love5an
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.