Folks It seems that I forgot to send this message a couple of weeks ago. Assuming that silence meant assent, I implemented the proposal below in the report I put out yesterday. But in this case silence meant you hadn't been asked (an excellent way to reach consensus that I must remember for the future). So here's the message anyway. I don't think it's controversial, since it's the outcome the cognoscenti were seeking, and no one else will care. Well, so I hope! Simon | > In short, an import *always* brings the entire *qualified* | > set of names into scope. Hiding and revealing applies only | > to unqualified names. I must say that I thought GHC implemented | > this rule; if not I should fix it. | | That's not my reading of the report, and it's not what GHC implements. | | import A (f) | | brings only f and A.f into scope. How embarassing. Now I look at it (yet) again, the report is certainly ambiguous about whether import A(f) imports A.g as well. But SimonM is right to say that the implication is that it does *not* (contrary to my earlier message). But if it does not, then the treatment of hiding and explicit-listing is inconsistent, which is a Bug. There are two consistent positions 1. Every import of module A (no matter how constrained) imports all of A's exports with qualified names. Import of qualified names is unaffected by both hiding clauses and the explicit entity list 2. The explicit entity list, or hiding clause, for an import determines which entities are imported. The qualified names of all these entities are brought into scope; in addition, for an unqualified import the unqualified names are brought into scope too. Everyone who has spoken favours (2), and indeed GHC implements it. So I propose to change the report to say that much more explicitly. Any objections? Simon
Option 2 is closer to what the syntax of imports, read as English, suggests is intended, but, if it wasn't for that, I'd be promoting option 1. The primary purpose of being able to restrict imports is to avoid name clashes, and with qualified import there is no risk of a clash, so no need for restrictions. Even with option 2, there is scope for confusion. "Import" without "qualified", imports both qualified and unqualified names, but adding the word "qualified" doesn't make any difference to the position of qualified names, but instead silently fails to import unqualified names. There is still a strange asymmetry, too. Whereas adding "qualified" to "import Modname ( a, b, c)" doesn't change which entities are imported, just the ability to refer to them by unqualified names, adding qualified" to "import Modname hiding ( a, b, c)" has the effect of importing everything that was previously hidden. Personally, I think the right solution is to import entire modules (the exported parts) qualified, and optionally to allow unqualified reference to some or all names, with a syntax like import modid [as modid] [unqualifying ( [all except] impspec] | all) but it's probably too late for this. --brian Simon Peyton-Jones wrote:
Folks
It seems that I forgot to send this message a couple of weeks ago. Assuming that silence meant assent, I implemented the proposal below in the report I put out yesterday. But in this case silence meant you hadn't been asked (an excellent way to reach consensus that I must remember for the future).
So here's the message anyway. I don't think it's controversial, since it's the outcome the cognoscenti were seeking, and no one else will care. Well, so I hope!
Simon
| > In short, an import *always* brings the entire *qualified* | > set of names into scope. Hiding and revealing applies only | > to unqualified names. I must say that I thought GHC implemented | > this rule; if not I should fix it. | | That's not my reading of the report, and it's not what GHC implements. | | import A (f) | | brings only f and A.f into scope.
How embarassing. Now I look at it (yet) again, the report is certainly ambiguous about whether import A(f) imports A.g as well. But SimonM is right to say that the implication is that it does *not* (contrary to my earlier message). But if it does not, then the treatment of hiding and explicit-listing is inconsistent, which is a Bug.
There are two consistent positions
1. Every import of module A (no matter how constrained) imports all of A's exports with qualified names. Import of qualified names is unaffected by both hiding clauses and the explicit entity list
2. The explicit entity list, or hiding clause, for an import determines which entities are imported. The qualified names of all these entities are brought into scope; in addition, for an unqualified import the unqualified names are brought into scope too.
Everyone who has spoken favours (2), and indeed GHC implements it. So I propose to change the report to say that much more explicitly.
Any objections?
Simon
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
-
Brian Boutel wrote
Option 2 is closer to what the syntax of imports, read as English, suggests is intended, but, if it wasn't for that, I'd be promoting option 1. The primary purpose of being able to restrict imports is to avoid name clashes, and with qualified import there is no risk of a clash, so no need for restrictions.
This is not true since Haskell allows for the renaming of modules on imports. If you look at the example in section 5.3.2 of the report, there is the example module M where import qualified Foo as A import qualified Bar as A x = A.f Obviously there is a name clash if both, Foo and Bar export symbol f.
Even with option 2, there is scope for confusion. "Import" without "qualified", imports both qualified and unqualified names, but adding the word "qualified" doesn't make any difference to the position of qualified names, but instead silently fails to import unqualified names.
I don't understand what confusion you see here. What do you mean by the "position of names"?
There is still a strange asymmetry, too. Whereas adding "qualified" to "import Modname ( a, b, c)" doesn't change which entities are imported, just the ability to refer to them by unqualified names, adding qualified" to "import Modname hiding ( a, b, c)" has the effect of importing everything that was previously hidden.
I don't see that this applies to option 2. Maybe the formulation is still not clear enough, but in my reading (and I think this is the intended one) it says that the list of imported entities is the same regardless of whether you use qualified on the import or not. The qualified keyword only prevents the use of unqualified references to these entities. So if in your example the module Modname exports entities a, b, c, d, and e, then after import Modname hiding (a,b,c) only d and e are imported and then same is true for import qualified Modname hiding (a,b,c)
Simon Peyton-Jones wrote: [...]
There are two consistent positions
1. Every import of module A (no matter how constrained) imports all of A's exports with qualified names. Import of qualified names is unaffected by both hiding clauses and the explicit entity list
2. The explicit entity list, or hiding clause, for an import determines which entities are imported. The qualified names of all these entities are brought into scope; in addition, for an unqualified import the unqualified names are brought into scope too.
Regards Wolfgang -- Wolfgang Lux Phone: +49-251-83-38263 Institut fuer Wirtschaftinformatik FAX: +49-251-83-38259 Universitaet Muenster Email: wlux@uni-muenster.de
Wolfgang Lux wrote:
Brian Boutel wrote
Option 2 is closer to what the syntax of imports, read as English, suggests is intended, but, if it wasn't for that, I'd be promoting option 1. The primary purpose of being able to restrict imports is to avoid name clashes, and with qualified import there is no risk of a clash, so no need for restrictions.
This is not true since Haskell allows for the renaming of modules on imports. If you look at the example in section 5.3.2 of the report, there is the example
module M where import qualified Foo as A import qualified Bar as A x = A.f
Obviously there is a name clash if both, Foo and Bar export symbol f.
Obviously you can rename modules to create a name clash, but it seems a silly thing to do. What I was trying to say was that in module M where import Foo import Bar hiding f where both Foo and Bar export f, there is no reason to not import all the qualified names in Bar, because no name clash will result if you do. However, this argument is now moot, becaue the resolution of this issue is now clear, and is good enough. --brian
Simon Peyton-Jones wrote: | [..modules..] So here's the message anyway. I don't | think it's controversial, since it's the outcome the | cognoscenti were seeking, and no one else will care. That is not true! I do care! :-) Often, after having been bitten by a misunderstanding of the Haskell module system, I have often wondered why the following two facts are consistent: 1. Haskell has a simple module system. 2. There exists no comprehensive description of it, nor do there exist two compilers who seem to implement the same thing. The answer is, of course, that one of these "facts" is false (namely 1.). I have often tried, but never succeeded, to understand what the report says and at the same time unify it with what the particular compiler I was using actually implemented. What I would like to see in the report are *examples*. Namely what happens in each of the following cases: import A import A() import A(x,y) import qualified A import qualified A() import qualified A(x,y) import A hiding () import A() hiding () import A(x,y) hiding () import A hiding (p,q) import A() hiding (p,q) import A(x,y) hiding (p,q) import qualified A hiding () import qualified A() hiding () import qualified A(x,y) hiding () import qualified A hiding (p,q) import qualified A() hiding (p,q) import qualified A(x,y) hiding (p,q) Where A is a module exporting the names x, y, p, q, v, w. Honestly, in some of these case I do not understand if 1) it is legal syntax, and if so, 2) what happens, and, if not so, 3) why not. Certainly, some of the above are equivalent? (At least when you take semantics nr 1. from Simon's e-mail). /Koen.
Koen Claessen wrote
What I would like to see in the report are *examples*. Namely what happens in each of the following cases:
Ok, let me try:
import A visible: x, y, p, q, v, w, A.x, A.y, A.p, A.q, A.v, A.w
import A() nothing imported
import A(x,y) visible: x, y, A.x, A.y
import qualified A visible: A.x, A.y, A.p, A.q, A.v, A.w
import qualified A() nothing imported
import qualified A(x,y) visible: A.x, A.y
import A hiding () like import A
import A() hiding () import A(x,y) hiding () these two are not legal, you have either and list of included entities or a list of hidden entities both not both.
import A hiding (p,q) according to report this would import x, y, v, w, A.x, A.y, A.p, A.q, A.v, A.w with the revision of the report A.p and A.q no longer are visible
import A() hiding (p,q) import A(x,y) hiding (p,q) both are not legal
import qualified A hiding () like import A import qualified A() hiding () import qualified A(x,y) hiding () both not legal
import qualified A hiding (p,q) either A.x, A.y, A.p, A.q, A.v, A.w (according to the report) or A.x, A.y, A.v, A.w (when the report is changed as Simon proposed)
import qualified A() hiding (p,q) import qualified A(x,y) hiding (p,q) both not legal
Regards Wolfgang -- Wolfgang Lux Phone: +49-251-83-38263 Institut fuer Wirtschaftinformatik FAX: +49-251-83-38259 Universitaet Muenster Email: wlux@uni-muenster.de
participants (5)
-
Brian Boutel -
Brian Boutel -
Koen Claessen -
Simon Peyton-Jones -
Wolfgang Lux