问题
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