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?
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.
The answer I posted here about (begin ())
is another acceptable reason to use begin in (if () )
statements.