Я использую 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?