Why is (begin) valid in Scheme?

2019-06-24 00:42发布

问题:

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.



标签: scheme racket