[R6RS] modules

R. Kent Dybvig dyb
Sun Aug 22 12:48:06 EDT 2004

> "But, but, but, ... what about ME!?"

> I guess I'm a bit disappointed that you didn't take up any (that I
> could see) of my arguments in the thread between Matthew and myself.

That is unfortunate, and it may be that we just don't understand your
point of view, much as I didn't understand some of Matthew's until we
spoke.  Perhaps we'll have better luck when we meet in person.  Email is
great, but it's often a poor substitute for interactive communication.

> - I still fail to see why the top-level module system and the
>   local-scope one should be the same.

> - In fact, nobody has introduced a specific rationale for a
>   local-scope module system at all---Matthew asked for examples ages
>   ago, but never got any.

No one has introduced a local module construct.  To be clear: the module
construct that Matthew and I agree to be useful is a wrapper on a library
file, specifying what language the code in the file is written in,
kind of like a generalized magic word or filename extension.

While I do believe local module constructs to be useful, I will hold off
giving my rationale until we decide it's time to discuss local modules.

I did give multiple rationales for allowing local requires:

>  * Require forms should be allowed in arbitrary local scopes to provide
>    finer control over visibility.  Local require forms can also help
>    prevent stale requires (requires that were once needed for a small
>    portion of the module that has since been removed or rewritten).
>    They can also obviate some renaming of imports.

One more thing: local require forms can lead to less overhead at compile
time and less bloat and overhead at run time.  If module B exports
two items x and y and only x requires module A, then an application
importing only y from module B need not load module A.  (This may be
tricky to implement when x is a procedure, but it is trivial when x is
a macro that expands into a require of A.)

> Now, I believe Richard, Manuel and I have presented rationales for:

> - separate interfaces

As I said in my note, I do not wish to preclude separate interfaces,
but I don't think they are useful enough to require the extra syntactic
overhead in all cases.

Negative rationales are always tricky, but I'll try to express why I
don't think separate interfaces are "useful enough":

  * Any specification of an interface without syntax definitions (if any)
    is incomplete, i.e., won't support independent compilation or
    analysis.  While separate interfaces can be useful documentation,
    a tool that examines (expands and scans or analyzes) a module can
    provide even better information on demand (as well as the information
    necessary to separately compile dependent modules and applications).

  * Separate interfaces for modules that happen not to export syntax
    do support independent compilation and analysis, but I would prefer
    not to encourage two-tiered systems where one can get independent
    compilation for modules that don't export syntax but not for those
    that do, since this may lead people away from the use of exported
    syntax.  I'd rather we encourage the development of usable systems
    that support exported syntax fully.

  * We could include syntax definitions in the (separate) interface,
    but I prefer that they be part of the implementation where
    they have the same (implementation-hiding) status as other code.
    More importantly, I don't want to have to break apart abstractions
    that produce both syntax and variable definitions into ones that
    provide them separately, which is bad on multiple levels.

Please note the distinction I'm making between independent and separate
compilation.  By "independent" I mean that a module that requires
another module can be fully compiled with no information about the
implementation of the other module.  By "separate" I mean compilation
can occur at different times, but not necessarily without information
gleaned from the actual implementation of the other module.  All of
our proposals to date support separate compilation, and non generally
support independent compilation.

Nevertheless, to be clear: it's fine with me if separate interfaces are
allowed.  I just prefer they not be required (in the natural-language
sense of the word "require").

> - a module language that isn't conflated with the regular language

The only conflation is allowing local requires of top-level modules,
and I did give a rationale for that.

A middle ground is to separate the "which module" and "which identifiers"
parts of a require form.  The module header can specify which other
modules it needs while the actual set of imported bindings can be
specified more locally.  This allows fine control over scope but not
over module relationships, so while namespace clutter is reduced as
well as the need for renaming of imports, stale requirements and extra
overhead are still potential problems.  (Matthew and I discussed this
middle ground and both prefer full local require.)

> - allowing several module definitions in one file

I have no problem with this, especially if we end up using module names
to identify modules rather than normalized filenames.


More information about the R6RS mailing list