[plt-dev] syntax/module-reader and #%module-begin

From: Sam TH (samth at ccs.neu.edu)
Date: Mon Nov 30 13:53:19 EST 2009

On Mon, Nov 30, 2009 at 1:32 PM, Carl Eastlund <cce at ccs.neu.edu> wrote:
> On Mon, Nov 30, 2009 at 1:29 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>> On Mon, Nov 30, 2009 at 11:14 AM, Carl Eastlund <cce at ccs.neu.edu> wrote:
>>> Modules have this weird property: they behave differently if they have
>>> exactly one element in their body, than if they have zero elements, or
>>> two or more elements.  They expand that body element looking for
>>> #%module-begin.  If they have zero, or two or more, elements, they
>>> wrap those elements in #%module-begin.  The #%module-begin form does
>>> "most of the work" of expanding modules, so in the one-element-only
>>> case, there is a period of expansion during which #%module-begin is
>>> "not at the helm".  I bring this up because it caused a problem for
>>> Stevie (resulted in a bug report about #lang scheme/signature, in the
>>> case where a module contains precisely one form that is a use of
>>> "contracted").
>>>
>>> Most of our #langs are written with syntax/module-reader, which reads
>>> in a bunch of forms and wraps them in (module foo lang <FORM> ...).
>>> The problem above would go away if instead it wrapped the forms in
>>> (module foo lang (#%module-begin <FORM> ...)).  The only thing this
>>> gives up is the ability to fill in a custom #%module-begin, but... who
>>> does that, and why would one?
>>
>> I'm not sure I understand. But I have a custom #%module-begin that
>> does expansion and compilation in the Web languages. I believe that TS
>> does that too.
>
> What I have proposed preserves custom #%module-begin.  It adds the one
> from the module in question.  This is only about *when*, during the
> expansion process, the language's #%module-begin gets added, not which
> binding is used.

To give a little more detail, right now you can do this:

#lang scheme
1 2 3

and this reads as, roughly:

(module foo scheme
  1 2 3)

which expands in one step to:

(module foo scheme
   (#%module-begin
     1 2 3))

with the `#%module-begin' being the one from `scheme'.

You can also do this yourself:

#lang scheme
(#%module-begin
  1 2 3)

which reads as:

(module foo scheme
  (#%module-begin
    1 2 3))

which doesn't add an additional `#%module-begin', thanks to a special
case in the `module' expander when there is exactly 1 form in the
module body.  As far as advantages of this, the only thing you can do
is something like this:

#lang scheme
(#%plain-module-begin
  1 2 3)

which won't print 1 2 3 the way the regular `#%module-begin' would.
This *only* works for languages that provide *both* `#%module-begin'
as well as some other for (here `#%plain-module-begin') that works as
a module-begin form.  I think that only `scheme' and `scheme/base' are
like that.

If we adopted Carl's proposal (which I support), you would have to write:

(module foo scheme
  (#%plain-module-begin
     1 2 3))

if you wanted to use a different module-begin binding from the language.
-- 
sam th
samth at ccs.neu.edu


Posted on the dev mailing list.