[racket-dev] internal-definition parsing
On Wed, Jul 7, 2010 at 12:23 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> Should an expression be required at the end? A `module', `unit', or
> `class' body can consist of just definitions. Similarly, if an
> internal-definition context ends with a definition, we could define the
> result to be `(void)', which is what the `block' form does.
>
> I think it's better to require an expression at the end, partly on the
> grounds that the internal-definition block is supposed to return a
> value (unlike the body of `module', etc.) and partly to avoid making
> forms like
>
> (define (f x)
> x
> (define (g y)
> y))
>
> legal when they are almost certainly mistakes.
Macros constructing sequences of def-or-expr for implicit begin (as
found in let, lambda, parameterize, etc.) won't always know if the
sequence is empty or non-empty, and whether it is terminated by an
expression or definition. If a begin-like sequence ends with a
definition, currently a macro must add an expression such as (void) to
follow it. If it ends with an expression, the macro must *not* add
such an expression, because that changes the return value. It would
be far more convenient if primitive forms worked with any sequence of
def-or-expr so that each wrapper macro did not have to implement its
own local-expand loop to figure out how the sequence ends, and as
always it is much nicer to write macros when sequences can be
zero-length.
--Carl