[R6RS] modules

R. Kent Dybvig dyb
Tue Aug 24 12:12:37 EDT 2004

>      * 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.

> I disagree with this.  The compiler can easily identify and indicate
> stale requires much more accurately than a programmer.

Perhaps, but I'd rather write my code more precisely in the first place
and not depend on a tool, and you have not addressed the other benefits
of local requires.

> I wouldn't object to a local require that
> had a body and explicitly named the identifiers being introduced.

I prefer that the decision to explicitly name identifiers be up to
the programmer, but I would go along with this if necessary to reach

I assume by "having a body" you wish to rule out require as an internal
definition form.  I don't understand why this helps with the scoping
issue you mentioned.

I've come to like internal defines in spite of my early opposition to
them because they allow me to have mutually recursive variable, syntax,
and derived definitions and because they lead to less indentation (call
me superficial if you like).  It's not going to be easy to convince me
to give them up.

>      * 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.)

> I'm unclear on both the question and the consequences of choosing one
> or the other.  By 'module expresions and commands' do you mean the
> code in the body of the module?


> If so, doesn't evaluating each module
> only once allow contagion between compile time and run time?

Yes.  So does the file system.  I'd prefer that my system not read
configuration files, build translation tables, etc., multiple times in
a vain effort to prevent me from doing something "bad" that I can do in
some other way anyway.

> I would like to drop the pathname entirely.  Failing that, it should
> be advisory.

Would you have a separate way to associate names with pathnames, or do
you prefer that modules be explicitly loaded?

> Not settable.  I would like to go further and prohibit any assignment
> of exported variables, including in the exporting module.  SET! on a
> an exported variable is rare enough that it's nice to know that it
> can't happen at all.

Does this include implicit exports?

>      * 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.)

> No.  Implicit exports are the business of the implementation, not the
> programmer.  This seems akin to requiring that the programmer list the
> closed-over variables in a lambda.

>From an aesthetic point of view, I agree with you.  Unfortunately, the
implementation cannot generally determine from a module alone,
i.e., without knowing how it is used, the module's implicit exports.
By recursively searching through the syntax objects of exported macros,
we can determine an initial set of implicit exports, then compute the
transitive closure of this set to make a conservative approximation of
the set of implicit exports.  These syntax objects may include arbitrary
data, including possibly cyclic data, that will end up quoted.  This is
a complicated and potentially expensive process that forces us to scan
through data we would not otherwise have to scan and in the end yields
imperfect information that hinders static analysis, copy propagation,
inlining, etc.


More information about the R6RS mailing list