Ошибка при расширении макроса в Chicken Scheme
Я изучаю, как работает система макросов в Scheme, и пытаюсь сделать мой код более похожим на JavaScript. Поэтому я подумал, что начну с function
макро. Вот как я хочу, чтобы определение функции выглядело так:
(function id (x) x)
Следует расширить до следующего:
(define (id x) x)
Поэтому я пишу макрос следующим образом:
(define-syntax function
(lambda (name args . body)
`(define (,name ,@args) ,@body)))
Однако, когда я использую его, я получаю следующую ошибку (в Chicken Scheme):
Error: during expansion of (define ...) - in `define' - lambda-list expected: (define ((function id (x) x) . #<procedure (rename sym1348)>) #<procedure (compare s11400 s21401)>)
Call history:
<syntax> (function id (x) x)
<eval> (##sys#cons (##core#quote define) (##sys#cons (##sys#cons name args) body))
<eval> (##sys#cons (##sys#cons name args) body)
<eval> (##sys#cons name args) <--
Куда я иду не так? Кроме того, как мне прочитать такие сообщения об ошибках, чтобы можно было отлаживать программу самостоятельно?
2 ответа
В Схеме, используя синтаксические правила ():
(define-syntax function
(syntax-rules ()
((function name (args ...) body ...)
(define (name args ...) body ...))))
Ошибка, которую вы видите, заключается в том, что, по-видимому, компилятор Chicken Scheme ожидает вторую форму define-syntax
чтобы быть процедурой расширения макроса - им обычно требуются аргументы для переименования и сравнения идентификаторов. lambda
в вашем макросе не выдает подходящую функцию - syntax-rules
делает.
Вышеуказанное гарантировано гигиеническое.
То, как вы определили макрос, неверно согласно документации Chicken. Ваш код, кажется, больше вдохновлен макросами Common Lisp. Проверьте документ здесь для define-syntax
с функцией трансформатора:
Макрос должен быть определен как:
(define-syntax function
(lambda (expr inject compare)
`(define (,(cadr expr) ,@(caddr expr)) ,(cadddr expr))))
expr - это целое выражение макроса, т.е. (function id (x) x)
и инжектировать и сравнивать - это специальные служебные функции, передаваемые макросу при выполнении раскрывающегося макроса.