Я запускаю Chez Scheme 9.5 и пытаюсь определить синтаксический преобразователь в библиотеке. Вот пример:
(library (forlib)
(export for)
(import (rnrs (6)))
(define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
Я сохраняю это в файле forlib.ss
и запускаю chez
из того же каталога. Затем в REPL я получаю это:
> (import (forlib))
> (for x in '(1 2 3) (display x))
Exception: invalid syntax (for x in (quote (1 2 3)) (display x))
Type (debug) to enter the debugger.
Если я изменю определение синтаксиса на
(define-syntax for
(syntax-rules ()
[(for x lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
(без ключевого слова in
) все работает:
> (import (forlib))
> (for x '(1 2 3) (display x))
123
> _
Вернуться к старому определению с ключевым словом in
. Если я помещу тестовый код в тестовый файл:
;;; test-for.ss
(import (rnrs (6))
(forlib))
(for x in '(1 2 3) (display x))
и попытаться выполнить этот файл, результат зависит от того, как я выполняю файл. Если я запускаю эту программу, используя chez --program
, она работает так, как ожидалось:
$ chez --program test-for.ss
123
$ _
Если я запускаю его с помощью chez --script
, я получаю ту же ошибку, что и выше:
$ chez --script test-for.ss
Exception: invalid syntax (for x in (quote (1 2 3)) (display x)) at line 6, char 1 of test-for.ss
$ _
Это вызывает два вопроса:
- Почему REPL и
--script
нормально импортируют синтаксические формы без специальных ключевых слов, но отказываются принимать синтаксические формы, в которых есть специальные ключевые слова? - В чем именно разница между
--script
и--program
? В руководстве пользователя сказано, что--program
означает, что содержимое файла интерпретируется как программа верхнего уровня rnrs, но ничего не говорится о семантике--script
.
Наконец, чтобы довести мою путаницу до конца, если я введу приведенное выше определение синтаксиса непосредственно в REPL, тогда все будет работать так, как ожидалось:
> (define-syntax for
(syntax-rules (in)
[(for x in lst body1 body2 ...)
(for-each (lambda (x) body1 body2 ...) lst)])))
> (for x in '(1 2 3) (display x))
123
> _
Так чем же отличаются в REPL преобразователи синтаксиса, импортированные из библиотеки, и преобразователи синтаксиса, определенные непосредственно в REPL?
in
, как вы предлагаете, я бы получил сообщение об ошибке, потому что вforlib
не определено имя для экспорта. Как указано ниже @gmw, для того, чтобы это работало,forlib
необходимо создать фиктивное имяin
, которое можно экспортировать. - person Norbert Zeh   schedule 21.01.2019