[racket-dev] internal-definition parsing

From: Eli Barzilay (eli at barzilay.org)
Date: Wed Dec 17 04:10:49 EST 2014

Another attempt at this old thing -- the idea of having some internal
`#%begin' thing (see ancient context below):

`begin' is something that is not only a ";" because of how it
sequences things, it's also a "return" thing -- it can be read as
(begin x ... y) ~ { x; ...; return y; }.  So maybe a `#%begin' should
take its context from its last expression?

It looks to me like this could be a similar case to `#%app' usually
doing the right thing, and easy to resolve when it isn't, as in
converting a macro like

    (define-syntax-rule (noisy x ...)
      (begin (displayln 'start) x ... (displayln 'start)))

to:

    (define-syntax-rule (noisy x ...)
      (begin (displayln 'start) (begin x ...) (displayln 'start)))



On July 7th 2010, Matthew Flatt wrote:
> 
> An Implicit Internal-Definitions Form
> -------------------------------------
> 
> Many forms --- including `lambda' `let', and the function-shorthand
> variant of `define' --- support internal definitions. The handling
> of internal definitions is currently tired to the form.
> 
> An alternative would be to have those forms implicitly wrap a group
> of internal-definition forms with `#%body', in much the same way
> that an application form is converted to a use of `#%app'. Then, the
> treatment of internal definitions could be independently configured
> through a module import. For example, one module might use a
> `#%body' that corresponds to the old handling of internal
> definitions, while another module could import a `#%body' that
> corresponds to the new handling.
> 
> Setting aside the backward-compatibility issues of adding an
> implicit form, I think it turns out not to work as well as
> `#%app'. The problem is that there's not a good place to get the
> lexical context to use for the implicit `#%body'. We have many
> macros analogous to
> 
>  (define-syntax-rule (squawk body ...)
>    (begin
>      (displayln "squawk!")
>      (let () body ...)))
> 
> If you take the lexical context from the parentheses that surround
> the `let' form, then the `#%body' is drawn from the context of the
> `squawk' definition, while the intent was more likely to get it from
> the use of `squawk'. Meanwhile, the `body ...' sequence itself
> doesn't necessarily have a lexical context (since it doesn't have a
> parenthesis, roughly), and the sequence is recreated by the macro
> implementation anyway.
> 
> This problem happens occasionally with `#%app'. When a use of
> identifier macro expands in an application position, for example,
> the implementor of the identifier macro usually should copy the
> lexical context of the old application form to the expansion
> result. Such cases are more rare than examples like `squawk',
> though.
> 
> So, an implicit `#%body' form seems like a good idea in principle,
> but it doesn't seem to work out well with our current syntax. I'm
> currently inclined to not change Racket and to treat this as
> something to support better the next time we define a core syntax,
> but I'm interested in further discussion.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.