问题描述
我在 Racket 和 Chez Scheme 中进行了测试,发现 (begin)
是可以接受的,而 (define a (begin))
不是.例如我得到的球拍
I have tested in Racket and Chez Scheme and found (begin)
is acceptable while (define a (begin))
is not. For example with Racket I got
> (begin)
> (define a (begin))
; stdin:56:10: begin: empty form not allowed
我的问题是为什么完全允许 (begin)
?这有什么具体的原因/直觉吗?
And my question is why is (begin)
allowed at all? Is there any specific reason/intuition for this?
推荐答案
表单 begin 有两个目的.
The form begin has two purposes.
1. To sequence the evaluation of expressions
2. To "splice" sequences together (used by macros)
第一个是最常用的:
(begin e0 e1 ...)
将按顺序计算表达式 e0 e1 ....
will evaluate the expressions e0 e1 ... in order.
当宏扩展为多个定义和/或表达式时使用第二个.
The second is used when a macro expands to multiple definitions and/or expressions.
以下面为例
(begin
(begin d1 e1 d2 d3)
(begin)
e2
...)
将被宏扩展器扁平化为:
will be flattened by the macro expander into:
(begin d1 e1 d2 d3 e2 ...)
现在是为什么(开始)完全允许?"的问题.如果 begin
用于目的 1(排序),则可能不允许使用空的 begin
.对于目的 2(拼接),使用 (begin)
作为一个什么都不做的宏的结果是非常方便的.考虑一个宏 (debug expression)
,它可以扩展为 expression
(启用调试时)或禁用调试时扩展为 (begin)
.
Now to the question "Why is (begin) allowed at all?". If begin
was used for purpose 1 (sequencing) then an empty begin
could be disallowed. For purpose 2 (splicing) it is very convenient to use (begin)
as the result of a macro that does nothing. Consider a macro (debug expression)
that either expands into expression
(when debugging is enabled) or into (begin)
when debugging is disabled.
这篇关于为什么(开始)在 Scheme 中有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!