У меня есть еще один вопрос о макросах Hygieni c в схеме, рассмотрим пример из R5RS
(let-syntax ((when (syntax-rules ()
((when test stmt1 stmt2 ...)
(if test
(begin stmt1
stmt2 ...))))))
(let ((if #t))
(when if (set! if 'now))
if))
Почему это соответствует, если шаблон имеет 3 аргумента и многоточие, которые могут совпадать пустой список?
Он вызывается с 2 аргументами if
и (set! if 'now)
. С чем следует связать ...
, если stmt2
можно связать с пустым списком? Это не Лиспы, если ... это просто ничто. Это правда?
Каким должно быть расширение, когда в этом контексте? Каково значение stmt2
?
Почему это не работает, но первый код работает?
(let-syntax ((when (syntax-rules ()
((when test stmt1 stmt2 ...)
(if test
(begin stmt1
stmt2 ...))))))
(when if 10))
это работает в Kawa, но не в Guile, заключается в том, что ошибка в Guile, и он на самом деле должен работать как в Kawa?
И еще один вопрос, почему он не оценивается в nil
? Если следующий элемент в списке после 10
, равен nil
, значит stmt2
должен быть nil
? R5RS не очень помогает в этом отношении.
Я спрашиваю об этом, потому что я только что закончил схему переименования для моей макросистемы в Схеме LIPS, и когда я сопоставляюсь с образцом, у меня есть сравнение stmt2
и nil
, а также осталось ...
. Следует ли в этом случае ...
просто игнорировать, а stmt2
должно быть nil
? И должно совпадать даже с тем, что в шаблоне на один символ меньше? Это действительно сбивает с толку.
Каким должно быть расширение последнего фрагмента кода?
РЕДАКТИРОВАТЬ:
Еще одна мысль
(let-syntax ((when (syntax-rules ()
((when test stmt1 . stmt2)
(if test
(begin stmt1
stmt2))))))
(when if 10))
Это работает в Kawa и возвращает nil
, как и ожидалось, но в Guile оно выдает исключение, я считаю, что схема Kawa будет лучше в следующем выражении c.
Но почему это даже соответствует шаблону, если мало аргументов?