为什么(begin)在Scheme中有效?

wln*_*ana 5 scheme racket

我在 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)允许?这有什么具体的原因/直觉吗?

soe*_*ard 4

表单开始有两个目的。

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)为禁用调试时。