[R6RS] modules

R. Kent Dybvig dyb
Fri Aug 20 01:39:49 EDT 2004

I have tried to summarize below the module system aspects that Matthew
and I agree upon along with those that we still may not agree upon or
have not really addressed.  I apologize for not getting this out sooner,
but I had to work on my own implementation and try to understand Matthew's
before I fully understood the issues.

I'll let Matthew speak up if I have misrepresented his viewpoints or if
I have missed anything important.



Here are some principles that I believe Matthew and I agree upon:

  * A standard form specifying the "language" in which a library is
    implemented should be wrapped around all libraries.

  * 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.
  * We need something like require-for-syntax for specifying when the
    expressions and commands within a module are evaluated.  I propose
    that we actually have three flavors:

      (require <spec> ...)
      (require only-for-syntax <spec> ...)
      (require also-for-syntax <spec> ...)

    possibly with some other syntax.

  * Separate interfaces should not be required.  (But I don't think
    either of us minds if they are permitted.)

  * The syntax given in Matthew's original post is a reasonable
    starting point.

Here are some that we may not agree upon:

  * Should every r6rs program have the same kind of wrapper as is
    required for libraries?  (Matthew prefers so; I prefer not.)

  * Should bindings established by run-time require shadow bindings
    that would otherwise be visible within transformers, and visa
    versa?  For example, if M exports x, does
      (let ([x 3]) (require only-for-syntax M) x)
    evaluate to 3 or to an out-of-context error?  (I prefer error;
    I'm not sure about Matthew.)
  * Related to the above, should module expressions and commands be
    evaluated once for each "level" of require/require for-syntax or
    just once the first time needed?  (I prefer once; I'm not sure
    about Matthew.)

  * How are modules identified?  Possibilities include by name and
    by normalized pathname.  (I prefer by name with the pathname being
    advisory---information about where to find the module if it isn't
    already loaded.  I believe that Matthew prefers by normalized
    pathname, which is what MzScheme currently does.)

Here are some that we did not talk about much if at all;

  * Are module exports settable by the exporting module and/or importing
    module? (I prefer that modules be used to control scope, not mutation
    policy, so I would say that variables are settable.  one can always
    export accessors/setters for hidden exports to obtain finer control.)

  * Can more than one module appear in a file?  (If modules are identified
    by normalized pathname, it probably makes sense to have only one
    module per file; otherwise more than one may be reasonable.)

  * Must one declare "implicit" exports, i.e., local identifiers,
    references to which may be contained in the expanded output of an
    exported macro?  (I prefer yes, since this improves security and
    gives the implementation a chance to treat the remaining variables
    more efficiently.)

More information about the R6RS mailing list