#scheme #lisp
#схема #lisp
Вопрос:
В чем разница между двумя define-macro ниже?
(define-macro (f x) ( x 2))
(define-macro (g x) (list ' x 2))
когда я вычисляю (f ( 2 3)), возникает ошибка, но вторая работает хорошо. Почему?
Комментарии:
1. как скомпилировать? какая ошибка? пожалуйста, включите полное сообщение об ошибке.
2.
define-macro
насколько я знаю, это не часть Scheme: вы должны указать, какую реализацию вы используете.
Ответ №1:
Макросы преобразуют код в новый код. Он делает это как можно раньше. Например. если вы используете макрос в функции, он обычно расширяется при создании этой функции задолго до выполнения кода.
(f ( 2 3))
применит функцию макроса f
со значением '( 2 3)
как x
. Он попытается, ( '( 2 3) 2)
результатом чего будет новый код, который полностью заменяет весь (f ( 2 3))
. Однако
не удается добавить список к числу, поэтому нет смысла создавать подобный макрос.
(g ( 2 3))
применит функцию макроса g
со значением '( 2 3)
как x
. Он попытается (list ' '( 2 3) 2))
получить результат ( ( 2 3) 2)
. Затем это дословно помещается в расположение кода (g ( 2 3))
, как будто это всегда было ( ( 2 3) 2)
до начала выполнения программы. Это работает, потому что ( ( 2 3) 2)
это допустимое выражение.
Важно понимать, что макрос не вычисляет значения. Он принимает код в одном формате и создает новый код в другом. например. мы можем сделать let1
(let1 x ( 10 2)
( x x))
И это должно быть переведено на
(let ((x ( 10 2)))
( x x))
Итак, макрос:
(define-macro (let1 name expression . body)
`(let ((,name ,expression)) ,@body))
ПРИМЕЧАНИЕ: define-macro
не указано ни в одной версии Scheme. Многие реализации sheme имеют defmacro
и define-macro
реализованы с немного другим синтаксисом и спецификацией. Код, который использует define-macro
, является для этого не кодом Scheme, а диалектом, продиктованным разработчиками. Мой код был протестирован в #lang racket
with (require compatibility/defmacro)
, но он может не работать в вашей реализации Scheme. Единственная переносимая макросистема в Scheme — это define-syntax
with syntax-rules
.