我正在运行 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 中有何不同?