On Wed, 2009-10-14 at 01:00 -0400, Aaron W. Hsu wrote:

> [...]
>
> So, the module system I propose consists of two forms:
> 
> <library> := (library [<name>] <exports> . <body>)
> <name> := #identifier | <r6rs library name>
> <exports> := (export <export-spec> ...)
> <export-spec> := #identifier | (#identifier #identifier ...)
> <body> := (#expr|#def #expr|#def ...)
> 
> 
> In the above form, [...] 
> I have also made the name of the library 
> optional. This is to allow for anonymous modules,

If <name> is optional, is this ambiguous?:

(library (export foo bar) (export))

Is the second subform the <name> and the third subform the <exports>?
Or, is the second subform the <exports> and the third subform the first
form of the <body>?

I think something like this disambiguates:

(define (library-form-parts lib-form)
  ;; Returns three values: the library name, the exports, and the body.
  (define (named)
    (values
     (cadr lib-form)
     (cdaddr lib-form)
     (cdddr lib-form)))
  (define (anonymous)
    (values
     #F
     (cdadr lib-form)
     (cddr lib-form)))
  (if (symbol? (cadr lib-form)) 
    (named)
    (if (eq? 'export (caadr lib-form))
      (if (and (pair? (cddr lib-form))
               (pair? (caddr lib-form))
               (eq? 'export (caaddr lib-form)))
        (named)
        (anonymous))
      (named))))

because we assume that if we get to (eq? 'export (caaddr lib-form))
being true, the second `(export ---)' is the <exports> and is not a form
of the <body> because `export' cannot possibly be bound yet in the scope
of the <body>.  In the very rare case it was intended that the second
`(export ---)' be the first <body> form and that the library be
anonymous, an unbound identifier error about `export' will not happen
and the library will be named what was intended to be the <exports>.
Because this case is very rare, and because I suppose this accident will
be noticed quickly, this method of disambiguating seems acceptable, but
I'm not certain.

> [...]
>
> I have removed, in the above, the import form. This is because this import  
> form should be usable anywhere, and is, in this proposed system, its own  
> form, and not a component of the library syntax.

If there is not an import form as part of the library form syntax, how
do we know what an import form in the <body> means?  There would have to
be an implicit binding of `import' to the thing which imports.  But that
would make `import' a special keyword which is always implicitly bound,
which does not seem Schemely.  What would this do?:

(library (some lib)
  (export)
  (import (thing base))
  (define import 'something-else))

`import' is implicitly bound at the library's top-level, so, the
definition of another `import' conflicts with the already-bound one.

If the implicitly-always-bound `import' was considered to be implicitly
imported, and if imported bindings could be shadowed by top-level
definitions, then the definition of another `import' would work.
However, allowing imported bindings to be shadowed by top-level
definitions is not compatible with R6RS.  I assume R6RS disallows such
shadowing for good reason(s).  One reason I can think of is that this
would not be clear:

(library (lib A)
  (export foo)
  (import (thing base)
          (only (lib B) foo))
  (define foo 'foo))

Which `foo' is exported?

If, in your proposal, imported bindings should not be shadowable by
top-level definitions, it seems an import form must be part of the
library form syntax.

Also, with implicitly-always-bound `import', what would this do?:

(library (some lib)
  (export m)
  (import (thing base)
          (thing syntax-case))
  (define-syntax m
    (lambda (stx)
      (syntax-case stx ()
        ((_ x)
         (free-identifier=? (syntax x) (syntax import)))))))

;; Outside of a library form:
(m import)  ;; #T or #F?

If `import' is implicitly bound in libraries' bodies, and if outside of
a library form it is not bound, `(m import)' will be #F.  I'm not sure
what to think about this.  Though, any environment outside of library
forms, in your proposal, I suppose would also always have `import'
implicitly bound, and so `(m import)' will be #T.

-- 
: Derick
----------------------------------------------------------------


_______________________________________________
r6rs-discuss mailing list
[email protected]
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss

Reply via email to