我在 Racket 和 Chez Scheme 中进行了测试,发现(begin)可以接受,但(define a (begin))不能。例如我得到的 Racket
> (begin)
> (define a (begin))
; stdin:56:10: begin: empty form not allowed
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么(begin)允许?这有什么具体的原因/直觉吗?
表单开始有两个目的。
1. To sequence the evaluation of expressions
2. To "splice" sequences together (used by macros)
Run Code Online (Sandbox Code Playgroud)
第一个是最常用的:
(begin e0 e1 ...)
Run Code Online (Sandbox Code Playgroud)
将按顺序评估表达式 e0 e1 ...。
当宏扩展为多个定义和/或表达式时,使用第二个。
举个例子,下面的
(begin
(begin d1 e1 d2 d3)
(begin)
e2
...)
Run Code Online (Sandbox Code Playgroud)
将被宏扩展器展平为:
(begin d1 e1 d2 d3 e2 ...)
Run Code Online (Sandbox Code Playgroud)
现在的问题是“为什么(开始)被允许?”。如果begin用于目的 1(测序),则begin可能不允许出现空值。(begin)对于目的 2(拼接),将其用作不执行任何操作的宏的结果非常方便。考虑一个宏(debug expression),它要么扩展为expression(启用调试时),要么扩展(begin)为禁用调试时。