This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home.

Ticket 132: Imports override previous imports?

2012-10-07 12:12:08
WG1 - Modules
alexshinn
major
cowan
wontfix
source
closed
2011-01-22 08:45:28
defect

In R6RS and therefore in our current module system, you can't import the same name from two different places. I think we should consider changing this so that you can (import (foo)) and then (import (override)), where (override) contains a subset of the names defined in (foo). Otherwise you have to say (import (except (foo) this that). This is no doubt safer, but also more annoying.

There are two sub-issues: allowing this at the REPL and/or allowing it in modules.

This requires that IMPORT be a normal form, which is not specified by ModulesShinn. What ticked deals with this issue?

Actually it is specified there; see the section on REPL Interaction. You'll note that it provides for overriding, so the remaining part of this ticket is whether the same can be done within a module.

Okay, I see the section on the REPL interactions, but I also see: “It is a syntax error if the same identifier is imported twice, from any combination of modules or multiple import forms.” This is for the module form. Moreover, ModulesShinn does not define an import form that is accessible in code. It is purely an element of the library form itself, so this question cannot apply to anything but the REPL unless we wish to introduce local imports.

Au contraire. We have already accepted imports overriding previous imports at the REPL per ModulesShinn. The question now is whether to change ModulesShinn so that imports into a module can override previous imports into that module. The case against it is that it makes the final result hard to predict; the case for it is improved convenience.

Ignoring REPL interactions, ModulesShinn already makes implicit shadowing in modules illegal. Moreover, I believe it a mistake to imply any sort of ordering on the module declarations, which implies that we should not allow more than one body or include form.

Not ordering the module declarations is fine; I'm now convinced that this ticket's proposal doesn't make sense in modules. Only allowing one code body, in the name of not having to concern yourself with how they are ordered, is absurd overkill.

The definitions in the bodies are order-independent anyhow, since you are not allowed to define an identifier more than once in all the bodies. So all that's left is the random expressions in the bodies, and ordering the bodies in the module controls how their execution is ordered. Otherwise, you're no better off than with R6RS and its single implicit body.

We have not bettered R6RS here, we have merely changed the syntax. Consider the following:

(library (code ...) (import ...) (include ...) (import ...) (code ...))

Assume the semantics you describe, then the above code contains some forms where order matters intermingled with some that do not. It matters in what order the code and include forms appear, but it does not matter where the import forms appear. I can see only one useful situation for this behavior: if we could expand into library forms, then it would be easier to write such macros, because we need not collect all the code before we insert some of it into the final expanded library form. We cannot expand into library forms; allowing this in WG1 gains us nothing but potential confusion.

On the other hand, such independence and partial ordering might make sense in WG2, and I would like to consider it there.

/me shrugs.

As a matter of style, imports should be bubbled to the top even if the syntax doesn't demand it. But interspersing exports with code bodies makes sense to me. (Hey, I like the Java style of tagging every definition as public or private.)

I object to making order appear to matter when it does not; I do not object to the use of ordering freedom to produce more readable code. Nonetheless, if you really want something like you say, then you ought to appreciate the full flexibility of a syntactic module language, which we do not have in WG1. In such a system, where export is just another form, implementing define/exported, which is a trivial macro, is better than the workaround you have suggested.

resolution
statusnewdecided

We voted this is an error.

statusdecidedwriting
resolutionwontfix
statuswritingclosed

Nothing to be done here.