[R6RS] Re: strawman module syntax

R. Kent Dybvig dyb
Fri Jul 9 15:28:53 EDT 2004


Thank you for the clarifications.  Unfortunately, I strongly dislike
several aspects of the proposed design.  One of Scheme's charms is that
3 is a program, and not just in the interactive environment.  There's no
barrier to entry, no boilerplate stuff to stick on the top of or wrap
around each file.  As long as I stay within the base language, I can
just start programming, and do so portably.  Another charm is that
there are no reserved words: I can redefine anything I want.  Another
is that macros can be used to specialize or generalize any language
construct---including, in Chez Scheme at least, module and import forms.
Another is that one can textually embed programs within other programs
to form larger programs, if some care is taken in the design of the
constituent parts.  The proposed design changes all of this because it
includes unnecessary restrictions with its useful new functionality.
The lack of such restrictions has helped make Scheme a good language,
and I see no reason to add them now.

Here are my suggestions:

1. Require the top level of any R6RS-conforming implementation to admit
   any mix of R6RS definitions and expressions.  Allow conforming
   implementations to admit implementation-dependent forms, but require
   conforming programs to avoid implementation-dependent forms.

   This would address several of the above concerns without hampering
   anyone's ability to write exactly the code the original proposal
   allows.

2. Treat both module and require (import) forms as definitions and
   allow them to appear anywhere where other definitions can appear.
   As with top-level definitions, top-level module forms may allow one
   to do things that don't make sense for internal module forms.  I
   see no harm in this.  Experience has shown that disallowing
   internal define-syntax was a bad idea; let's not repeat the mistake
   with modules.

   This addresses more of the above concerns, again without hampering
   anyone's ability to do what the original proposal allows.

   It also permits one to create extended (or restricted) versions of
   the module and require forms.  This in turn relieves us of some
   pressure to satisfy every need in the base syntax for modules.

3. Eliminate the implicit require form from the module syntax, scope
   modules where they appear, and introduce a special require form that
   blocks off the outside scope, like Chez Scheme's import-only.

   This allows us to expand into the (now no-longer implicit) require
   form used to specify the language.  Again, this is strictly a
   generalization of the earlier proposal; in fact, the original module
   form can be expressed as a macro.

4. Don't force the use of separate interfaces, i.e., allow one to
   require a named module rather than a named interface.  Don't support
   separate interfaces at all unless we have some portable mechanism
   for specifying which of multiple implementations is to used.

   There's no point in separate interfaces if only one implementation
   is available.  We can always generalize the identifier in, e.g.,
   (require id), to be an interface rather than a module if we wish to
   do so at some later point.

5. If we do support separate interfaces, they should include exported
   syntactic abstractions along with any nonexported syntactic
   abstractions (and meta definitions, if we support them) into which
   exported syntactic abstractions use or expand.

   Virtually nothing can be done with code that imports from an interface
   without the syntactic abstractions, so there's no point in knowing
   the interface before the syntactic abstractions are known.

There are some other things not specified by the proposal that we
need to hammer out, such as whether to include meta definitions or
require-for-syntax, whether to require hidden exports to be named, when
to evaluate module inits, and mutability rules for exported variables.
For the record, I prefer meta definitions and no require-for-syntax,
I prefer to require hidden exports to be named (which we must do anyway
if we ever go the route of separate interfaces), I prefer that module
inits be evaluated once when the module is first loaded, and I prefer
to allow exported variables to be mutated, since control over mutability
seems like an orthogonal issue.

Kent


More information about the R6RS mailing list