В этом случае реализация Racket R 6 RS не является несовместимой. На самом деле, во всяком случае, он более точно подчиняется стандарту: ваша программа в том виде, в котором она написана, не заботится о фазах импорта. Проблема в том, что define-syntax
оценивает свою правую часть во время развертывания, как указано в разделе 11.2.2 Определения синтаксиса:
Привязывает ‹keyword› к значению ‹expression›, которое должно оцениваться во время расширения макроса трансформатору.
В отличие от других стандартов Scheme, R 6 RS заботится о различении фаз, поскольку он разрешает произвольное программирование во время компиляции (в то время как другие стандарты Scheme этого не делают). Поэтому раздел 7.1 Форма библиотеки указывает, как импортировать библиотеки на определенных этапах:
Каждая «спецификация импорта» определяет набор привязок, которые необходимо импортировать в библиотеку, уровни, на которых они должны быть доступны, и локальные имена, по которым они должны быть известны. ‹Спецификация импорта› должна быть одной из следующих:
<import set>
(for <import set> <import level> ...)
‹Уровень импорта› может быть одним из следующих:
run
expand
(meta <level>)
где ‹level› представляет собой точный целочисленный объект.
Следовательно, вам нужно импортировать (rnrs base)
на фазах run
и expand
, и вам нужно импортировать (rnrs syntax-case)
на фазе расширения. Сделать это можно с помощью следующей программы:
#!r6rs
(import (for (rnrs base) run expand)
(for (rnrs syntax-case) expand)
(rnrs io simple))
(define-syntax stest
(lambda (x)
(syntax-case x ()
((_ z) #'(z 0)))))
(stest display)
Эта программа работает в Racket. Я не проверял, работает ли он также с другими реализациями схемы, которые вы указали, но должен ли они соответствовать стандартам.
person
Alexis King
schedule
12.06.2018