[R6RS] modules

R. Kent Dybvig dyb
Fri Aug 20 22:30:50 EDT 2004


> First, let me thank Kent Dybvig for posting his summary of issues.

You're welcome.

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

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

>     1.  no and yes
>     2.  yes and yes
>     3.  no and no
>     4.  yes and no  ---  this is a horrific combination of
>         misfeatures that thoroughly screws static analysis,
>         whether by compilers, tools, or humans

The issues are certainly related where implicit exports are concerned.
Based on Will's earlier answer, I assume that "no" to the first question
means that a module cannot assign imported variables but can assign
its own (implicit or explicit) exports.  So A below is presumably okay,
What about B, C, and D?

A. (module M (a? a!)     ; a? and a! are explicit exports
     (define x 0)
     (define-syntax a?   ; implicitly exports x
       (syntax-rules ()
         [(_) x]))
     (define a!
       (lambda (v)
         (set! x v))))

   (import M)
   (a! 17)
   (a?) ;=> 17

B. (module M (b? b!)
     (define x 0)
     (define-syntax b?
       (syntax-rules ()
         [(_) x]))
     (define-syntax b!
       (syntax-rules ()
         [(_ e) (set! x e)])))

   (import M)
   (b! 17)
   (b?) ;=> 17

C. (module M (c)
     (define x 0)
     (define-syntax c
       (syntax-rules ()
         [(_ set!) (set! x 17)])))

   (import M)
   (c set!)
   (c (lambda (x y) x)) ;=> 17

D. (module M (d)
     (define x 0)
     (define-syntax d
       (syntax-rules ()
         [(_ cons) (cons x 17)])))

   (import M)
   (d set!)
   (d (lambda (x y) x)) ;=> 17

I don't know where to draw the line, since variations of each of these
come in handy.  So Chez Scheme does not restrict assignments to exported
variables.  It does, however, require any nonexported variable x to be
listed as an implicit export with any macro that might expand into an
occurrence of x, e.g.,

A. (module M ((a? x) a!)
     (define x 0)
     (define-syntax a?
       (syntax-rules ()
         [(_) x]))
     (define a!
       (lambda (v)
         (set! x v))))

   (import M)
   (a! 17)
   (a?) ;=> 17

This limits the potential damage (from escaping references as well as
assignments) to (implicitly or explicitly) exported variables, allowing
the programmer and compiler to treat all other module variables as
entirely local.  Some such limit is necessary for us to have any hope
of analyzing a module separately from the code that imports from it.

Incidentally, I don't object to including a mechanism for creating
immutable variable bindings.  I just prefer that it be separate.

Kent


More information about the R6RS mailing list