Значением синтаксической привязки должно быть ключевое слово: альфа. Что это означает?

Вот моя небольшая программа:

(let-syntax ((alpha (lambda (x)
                      (list (syntax quote)
                            (list)))))
  (alpha))

И guile его выполняет и возвращает(). Но mit-scheme выводит следующее:

;Syntactic binding value must be a keyword: alpha
;To continue, call RESTART with an option number:
; (RESTART 1) => Return to read-eval-print level 1.

Почему?

(моя версия: Release 9.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/i386 4.118 || Edwin 3.116)


person Necto    schedule 28.10.2012    source источник
comment
Что ты пытаешься сделать здесь? Почему нет ключевого слова syntax-rules? Вы уверены, что хотите использовать let-синтаксис, а не одну из обычных версий let?   -  person itsbruce    schedule 30.10.2012
comment
Да это делается намеренно. Я изучаю механизмы макрорасширения низкоуровневой схемы. На самом деле я прочитал эту страницу: cs.indiana.edu/scheme-repository/ R4RS/r4rs_12.html   -  person Necto    schedule 30.10.2012
comment
Но вы неправильно используете механизм; там нет спецификации трансформатора. Чего вы надеетесь достичь?   -  person itsbruce    schedule 30.10.2012
comment
(лямбда (x) ...) — это преобразователь, который принимает объект синтаксиса x и возвращает объект синтаксиса '(#‹syntax quote›())). Это упрощение одного из примеров использования синтаксиса из этого URL, который я опубликовал.   -  person Necto    schedule 30.10.2012


Ответы (2)


Схема MIT предоставляет только syntax-rules, синтаксические замыкания и явное переименование для определения преобразователей синтаксиса. Для последних двух вам нужны формы sc-macro-transformer или er-macro-transformer. Если вы хотите использовать синтаксические объекты, вам потребуется реализация, поддерживающая синтаксические объекты (обычно поставляемая с syntax-case), например Рэкет или Коварство.

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

person Asumu Takikawa    schedule 10.11.2012

Документация, на которую вы ссылаетесь, явно демонстрирует, что вы обязательно должны использовать синтаксические правила с let-syntax. Вот точный синтаксический контракт.

    <macro block> ==>
          (let-syntax (<syntax spec>*) <body>)
         | (letrec-syntax (<syntax spec>*) <body>)
    <syntax spec> ==> (<keyword> <transformer spec>)
    <transformer spec> ==>
          (syntax-rules (<identifier>*) <syntax rule>*)

В соответствии со спецификациями нельзя ожидать, что использование чего-либо, кроме правил синтаксиса, будет работать без ошибок. Единственная причина, по которой это вызывает ошибку в MIT Scheme, а не в Guile, заключается в том, что в MIT Scheme более активно применяются исключения (то есть let-syntax MIT Scheme специально следит за тем, чтобы вы дали ему синтаксические правила). Это просто недопустимый код R4RS, и он не должен работать ни в одной реализации схемы, совместимой с R4RS.

person Alex V    schedule 10.11.2012