Hi all! I have been thinking about the scoping issues for imported names. Of course, this musing is ispired by the formal static semantics I have been working on, but it is also prompted by the revised Haskell report.
Section 5.5.2 relates to name clashes and has an interesting example towards the end: module F where sin :: Float -> Float sin x = (x::Float) f x = Prelude.sin (F.sin x) where the type signature refers to the local "sin" rather than the imported although none of them is visible unqualified. These rules are quite tricky to understand, I think. They are also different in spirit from the rules for instance declarations in section 4.3.2 where the binding occurrences for the names of the methods must be qualified if the unqualified method name is not in scope. In the "sin" example it is allowed to resolve the name clash using the "extra" knowledge that it is illegal to provide type signatures for imported names, wheras in the case for instance declarations we may not use the corresponding "extra" knowledge that only methods in the instance'd class may be bound by the bindings. What I'm driving at is this: I propose that top level bindings shadow imported names and that qualified names can not be used to refer to declarations in the same module. So. Now I've said it. It feels much better now. The first part is, as far as I can see, a compatible change. All programs will mean the same things as before but some additional programs will be legal. Of course, using qualified names to refer to top level declarations now becomes a redundant feature, and I would very much like it removed from the language, but this second change breaks programs. Maybe that is not acceptable for this revision and clarification. Or maybe it is? There is actually a mechanical translation from the old rules to the new: If the module name is M, then some occurences of qualified names of the form M.name, where "name" may be a name of a type, constructor, class or variable (including method or field name) refer to top level declarations in M itself. Call these "local qualified names". Now do the following: 1. For each occurrence of a local qualified name M.f such that "f" is also visible and refers to a different binding (which must be a nested binding), rename that binding (ie alpha convert it). 2. Replace any local qualified name M.name with name. So as far as incompatible changes go, this one is rather benign, I think. I think that accidental name clashes with imported names are annoying, but there are more formal reasons for that change. Consider the definition below, occurring in module M: f = ... M.f ... Is it recursive? That depends on whether it is top level or nested. It might also be illegal if there is an import declaration like import Foo as M (f) in the module, in which case there is a name clash between the imported M.f and the local one. This means that nested declarations have different semantics than top level declarations, which is unfortunate, or that the semantics of bindings such as these can only be given after renaming the module. Cheers, /kff who feels very relieved at having come out publicly in favour of shadowing imported names ;-) _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell