问题
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
And my question is why is (begin)
allowed at all? Is there any specific reason/intuition for this?
回答1:
The form begin has two purposes.
1. To sequence the evaluation of expressions
2. To "splice" sequences together (used by macros)
The first one is what is used most often:
(begin e0 e1 ...)
will evaluate the expressions e0 e1 ... in order.
The second is used when a macro expands to multiple definitions and/or expressions.
As an example, the following
(begin
(begin d1 e1 d2 d3)
(begin)
e2
...)
will be flattened by the macro expander into:
(begin d1 e1 d2 d3 e2 ...)
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.
回答2:
The answer I posted here about (begin ())
is another acceptable reason to use begin in (if () )
statements.
来源:https://stackoverflow.com/questions/41359441/why-is-begin-valid-in-scheme