[R6RS] `for' in `export'
Matthew Flatt
mflatt at cs.utah.edu
Fri Aug 25 17:58:39 EDT 2006
At Fri, 25 Aug 2006 01:04:02 -0400, dyb at cs.indiana.edu wrote:
> The library text is not in such good shape. There are some problems
> already with the description of phasing, some but not all of which I have
> tried to address, and we have to figure out how to account for the fact
> that both the phased and unphased models are now acceptable.
>
> Matthew, it would help if you could let me know how you think the library
> text needs to be modified to reflect both options and also let me know
> about any other changes you think need to be made to the text. The
> current document source is committed in srfi/library/library.stex,
> complete with a grammar that is currently broken and several FIXMEs.
Working...
And I see that I forgot to follow-up on the issue of exports and
phases.
Currently, we have a `for' specification in `export' that supplies a
default `for' to `import'. So,
(library (L)
...
(export (for (x y z) (meta 5) (meta 88)))
...)
causes
(import (L))
to mean "import x, y, and z for phases 5 and 88", whereas
(import (for (L) (meta 17)))
means "import x, y, and z for phases 17". In the latter case, the
`(meta 5)' and `(meta 88)' of export are ignored on `import', since the
`import' has an explicit `for'.
As came up in the discussion with Andre, I would much prefer that `for'
in `export' be *composed* with `for' in `import'. In that case, the above
declaration of `(L)' causes the same meaning for
(import (L))
but now
(import (for (L) (meta 17)))
means "import x, y, and z for phases 22 and 95".
There's another dimension to proposed change. In the current `for' of
`export', the named identifiers are all phase 0. I'd prefer that the
phase specified with `for' is the identifier's phase within the
exporting library. That is, the rule for exporting at phase N is the
same as referencing at phase N: the identifier must be defined at phase
N (which is possible only if N = 0) or imported at phase N.
This means the code behind "..." in the definition of `(L)' has to
change if `for' changes. With the current system, `x', `y', and `z' can
be defined as
(library (L)
...
(export (for (x y z) (meta 5) (meta 88)))
(define x ...)
(define y ...)
(define z ...)
...)
With the change I'm proposing, the programmer would have to write
(library (L-base)
...
(export x y z)
(define x ...)
(define y ...)
(define z ...)
...)
(library (L)
(import (for (L-base) (meta 5) (meta 88)))
(export (for (x y z) (meta 5) (meta 88))))
I find this extra-module overhead acceptable for the rare (I believe)
cases where you want a simple `import' to pull bindings into multiple
phases.
At the same time, you get new expressiveness with the new `for'. For
example, imagine that `(r6rs)' is implemented as
(library (r6rs)
...
(export (for (cons car cdr ...) run expand))
...)
Then
(library (M)
(import (for (r6rs) (meta 43)))
...)
works in a more natural way: a phase-43 expression can contain
`(let-syntax ([d (syntax-case ...)]) ...)' because `syntax-case' will
be imported into phase 44.
It also allows different subsets of bindings to be imported into
different phases. For example, an '(r5rs)' library might export
(export (for (syntax-rules) expand)
(for (cons car cdr ...) run))
to provide only `syntax-rules' in transformer expressions.
Overall, I think the change will work better in a model with phases ---
and, perhaps more importantly, will increase the likelihood that
programs implemented in a phaseless system actually work in a phased
system. Meanwhile, I don't think the changes are significant for a
phaseless system, as it only affects the way that the actual `for' of
an `import' is computed.
Thoughts?
Matthew
More information about the R6RS
mailing list