[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Begin flattening documentation bug (CC)



> This is because R4RS (section 5.2) specifies that begin
> flattening only occurs with definitions.  I.e.
>   (begin <definition>+)
> gets flattened, but
>   (begin <definition>+ <expression>+)
> does not.

> It is my opinion that BEGIN is a sequencing construct and
> unlike LAMBDA, LET, LET*, and LETREC, should *not*
> introduce a new lexical contour.  As it stands, any macro
> which introduces definitions and some other computation
> will have the above problem.

I think that Chez Scheme does what you would want it to do: it
uniformly treats (begin <stuff>) as the syntactic equivalent of <stuff>
within a <body>, so that, e.g.:

    (lambda args (begin <definition> <expression>))

is treated as the equivalent of:

    (lambda args <definition> <expression>)

Since the former is not a valid R4RS expression, other implementations
are permitted to treat it differently, and they can even signal an
error.

I'd like to see this changed too, but I'm not sure it's all that useful.
Referring back to your define-values example, it does allow you to write:

  (lambda --- (define-values ---) ---)

but not

  (lambda --- (define-values ---) (define-values ---) ---)

since the latter would transform into something with definitions and
expressions interspersed.  If you want to make sense of that, we're
starting down the slippery slope of allowing definitions to appear
anywhere within a lambda body.

Of course, we could say that a body is a sequence of expressions and
definitions containing at least one expression and treat it the same as
we now would treat a body in which all of the definitions appear before
all of the expressions.  For example:

   (lambda () (define x e1) (x y) (define y e2))

would be equivalent to:

   (lambda () (letrec ((x e1) (y e2)) (x y)))

I couldn't resist heading down the slope just a little way...