digitalmars.D - [frustration, sorry] Import conflict madness.
- Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= (16/16) Jun 17 2006 You write your great soft in D. You're coding with smile because everyth...
- Deewiant (5/12) Jun 17 2006 Seems to me that using "private import" instead of "public import" (the ...
- Derek Parnell (6/25) Jun 17 2006 I have yet to find a *need* for public imports.
- BCS (11/21) Jun 17 2006 A single-point-of-access module for a lib might count as a use. OTOH I
- Sean Kelly (8/10) Jun 17 2006 I have. Implementing C headers it's common for an alias to be declared
- Derek Parnell (13/21) Jun 17 2006 And yet I find it intuitive and helpful. People differ.
- Jari-Matti =?UTF-8?B?TcOka2Vsw6Q=?= (15/28) Jun 17 2006 I'm not that sure about that. This might be an oversimplified case, but ...
- Deewiant (7/12) Jun 17 2006 Quite correct.
- Chris Miller (18/18) Jun 17 2006 Here's a simple example of the issue:
- Jari-Matti =?UTF-8?B?TcOka2Vsw6Q=?= (10/41) Jun 17 2006 The compiler should say something like "function module1.foo is private ...
- Derek Parnell (11/18) Jun 17 2006 Maybe a message more like ...
- Bruno Medeiros (8/18) Jun 17 2006 5 or 6 releases? Far more than that, this bug
- Derek Parnell (9/23) Jun 18 2006 I was being generous and polite ;-)
- Georg Wrede (8/33) Jun 18 2006 How is anyone new to D supposed to even consider using it when stuff
- kris (4/20) Jun 18 2006 Dig dat, bro' ...
- Bruno Medeiros (7/31) Jun 19 2006 What do you mean? There are lot of testcases in DStress for protection
- Bruno Medeiros (8/39) Jun 19 2006 It's considering private imports because of bug 48, but this issue is
- Sean Kelly (43/51) Jun 17 2006 For what it's worth, the symbol resolution rules styled after the C++
- Bruno Medeiros (8/27) Jun 18 2006 I can't figure out what kind of parallel or comparison could be made of
- Sean Kelly (7/32) Jun 18 2006 C++ class member symbol lookup is roughly similar to module-level lookup...
- Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= (21/25) Jun 17 2006 OK. After some time I've finally discovered where the problem was and I ...
- Jari-Matti =?UTF-8?B?TcOka2Vsw6Q=?= (9/19) Jun 17 2006 I think they should be visible enough to trigger a proper error message,
- I hear ya (6/22) Jun 17 2006 You're write it is awful. A useful error message would make this a hund...
- Tom S (5/10) Jun 17 2006 Ummmm yeah... a lot...
You write your great soft in D. You're coding with smile because everything in seems to be so good. You added few new files, new classes. Porting your project from C++ to D seems to be so good idea. You type "make". And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29) GAME OVER! You're stuck with this nothing telling you error message. You start wondering what is wrong. Imports probably, but ... why? It takes 15 minutes of frustrating checking your files. You seek help on #D irc channel (nice people BTW) - but they can not help you. They can only tell "It might be that in some unrelated file you are trying to use map without importing map but are importing files that do import map" which is great help but still will require you to spend great amount of time finding this place. Please Walter - fix this. It is sooooooo frustrating and everyone confirms that. It's something that all D people hits once or more.
Jun 17 2006
Dawid Ciężarkiewicz wrote:Imports probably, but ... why? It takes 15 minutes of frustrating checking your files. You seek help on #D irc channel (nice people BTW) - but they can not help you. They can only tell "It might be that in some unrelated file you are trying to use map without importing map but are importing files that do import map" which is great help but still will require you to spend great amount of time finding this place.Seems to me that using "private import" instead of "public import" (the default) might help in locating this. When using "private import A;" in a module B, any other module that imports B does not automatically import A. I have long felt that private should be the default.
Jun 17 2006
On Sun, 18 Jun 2006 03:49:44 +1000, Deewiant <deewiant.doesnotlike.spam gmail.com> wrote:Dawid Ciężarkiewicz wrote:I have yet to find a *need* for public imports. -- Derek Parnell Melbourne, AustraliaImports probably, but ... why? It takes 15 minutes of frustrating checking your files. You seek help on #D irc channel (nice people BTW) - but they can not help you. They can only tell "It might be that in some unrelated file you are trying to use map without importing map but are importing files that do import map" which is great help but still will require you to spend great amount of time finding this place.Seems to me that using "private import" instead of "public import" (the default) might help in locating this. When using "private import A;" in a module B, any other module that imports B does not automatically import A. I have long felt that private should be the default.
Jun 17 2006
Derek Parnell wrote:On Sun, 18 Jun 2006 03:49:44 +1000, Deewiant <deewiant.doesnotlike.spam gmail.com> wrote:[...]A single-point-of-access module for a lib might count as a use. OTOH I have taken to doing all imports as private. import myBigLib; <code file="myBigLib.d> public import theFirstFile; public import theSecondFile; public import theThirdFile; ... </code>Seems to me that using "private import" instead of "public import" (the default) might help in locating this. When using "private import A;" in a module B, any other module that imports B does not automatically import A. I have long felt that private should be the default.I have yet to find a *need* for public imports.
Jun 17 2006
Derek Parnell wrote:I have yet to find a *need* for public imports.I have. Implementing C headers it's common for an alias to be declared in one header that must be visible in other headers. Sure, you could require the user to manually import both headers, but that's non-intuitive and a tad annoying. And the alternative (private import combined with aliasing symbols to expose them piecemeal) results in symbol collision problems. Sean
Jun 17 2006
On Sun, 18 Jun 2006 04:30:32 +1000, Sean Kelly <sean f4.ca> wrote:Derek Parnell wrote:And yet I find it intuitive and helpful. People differ. For me, if 'foo' is declared in A, and B needs to access 'foo' then B should import A. Now if C needs to access something in B and access 'foo' it should import both A and B. This seems natural to me. To do otherwise means that C's access to 'A.foo' becomes dependant on the implementation of B. This is too much cohesion in my books. And yes, it can result in the need to disambiguate public symbol references in C, but I see that as a good thing. It help document the code and reduces the chance of calling the wrong function. -- Derek Parnell Melbourne, AustraliaI have yet to find a *need* for public imports.I have. Implementing C headers it's common for an alias to be declared in one header that must be visible in other headers. Sure, you could require the user to manually import both headers, but that's non-intuitive and a tad annoying. And the alternative (private import combined with aliasing symbols to expose them piecemeal) results in symbol collision problems.
Jun 17 2006
Deewiant wrote:Dawid Ciężarkiewicz wrote:I'm not that sure about that. This might be an oversimplified case, but I think the problem comes up, when (A,B,C,D are modules here) B and C (privately) import A, and D imports both B and C. Now DMD regards function foo() in module A as B.foo() and C.foo() through the import chains. When D imports both B and C and a name conflict comes up, since they can't both become D.foo(). Ok, how do we fix this problem? A proper way to handle these would be IMO to save full info about the symbols and their origins in the symbol table. I'm not a compiler writer and haven't had much time to find out how this is done at the moment. But as a workaround you can (private) import B in module C. After that there's only one route to the symbol source.Imports probably, but ... why? It takes 15 minutes of frustrating checking your files. You seek help on #D irc channel (nice people BTW) - but they can not help you. They can only tell "It might be that in some unrelated file you are trying to use map without importing map but are importing files that do import map" which is great help but still will require you to spend great amount of time finding this place.Seems to me that using "private import" instead of "public import" (the default) might help in locating this. When using "private import A;" in a module B, any other module that imports B does not automatically import A.I have long felt that private should be the default.Yes. But imports should work properly, too. -- Jari-Matti
Jun 17 2006
Jari-Matti Mäkelä wrote:Deewiant wrote:Quite correct. <rant> Hell, "private" should work properly! As Sean Kelly posted to this thread, C++ has its (arguable) reasons for why "private members are inaccessible but not invisible", but D doesn't (seem to) have any. It's quite an annoyance, if not worse. </rant>I have long felt that private [import] should be the default.Yes. But imports should work properly, too.
Jun 17 2006
Here's a simple example of the issue: // -- foo.d -- private import std.stdio; // -- bar.d -- private import std.stdio; // -- test.d -- import foo, bar; void main() { char[] hi = std.string.toString(3); } DMD 0.160: foo.d(1): import foo.std conflicts with bar.std at bar.d(1) Of course, the code in test.d is a mistake, but look how unhelpful the error message is. It will blame a library's code for a mistake the library-user made. Also notice that it's considering *private* imports, which shouldn't even be available to test.d.
Jun 17 2006
Chris Miller wrote:Here's a simple example of the issue: // -- foo.d -- private import std.stdio; // -- bar.d -- private import std.stdio; // -- test.d -- import foo, bar; void main() { char[] hi = std.string.toString(3); } DMD 0.160: foo.d(1): import foo.std conflicts with bar.std at bar.d(1) Of course, the code in test.d is a mistake, but look how unhelpful the error message is. It will blame a library's code for a mistake the library-user made. Also notice that it's considering *private* imports, which shouldn't even be available to test.d.The compiler should say something like "function module1.foo is private and thus cannot be used in module2", when it's not accessible. The annoying thing is that when there's a function name conflict and the first conflicting function is privately imported and the other is publicly imported, the public version does not override the private one. And when the same symbol is imported using 2+ import routes, there's the same old bogus naming conflict again. -- Jari-Matti
Jun 17 2006
On Sun, 18 Jun 2006 04:15:11 +1000, Chris Miller <chris dprogramming.com> wrote:DMD 0.160: foo.d(1): import foo.std conflicts with bar.std at bar.d(1) Of course, the code in test.d is a mistake, but look how unhelpful the error message is. It will blame a library's code for a mistake the library-user made.Maybe a message more like ... foo.d(6): std.string is not accessible might be more useful for coders.Also notice that it's considering *private* imports, which shouldn't even be available to test.d.This has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't. -- Derek Parnell Melbourne, Australia
Jun 17 2006
Derek Parnell wrote:5 or 6 releases? Far more than that, this bug (http://d.puremagic.com/bugzilla/show_bug.cgi?id=48) was reported for DMD .149 and it was broken I don't know how many releases even before that. You said it used to work? When? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DAlso notice that it's considering *private* imports, which shouldn't even be available to test.d.This has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't. --Derek Parnell Melbourne, Australia
Jun 17 2006
On Sun, 18 Jun 2006 10:58:27 +1000, Bruno Medeiros <brunodomedeirosATgmail SPAM.com> wrote:Derek Parnell wrote:I was being generous and polite ;-)5 or 6 releases? Far more than that, this bug (http://d.puremagic.com/bugzilla/show_bug.cgi?id=48) was reported for DMD .149 and it was broken I don't know how many releases even before that.Also notice that it's considering *private* imports, which shouldn't even be available to test.d.This has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't. --Derek Parnell Melbourne, AustraliaYou said it used to work? When?The 'private' used to work at one stage because I tripped up on it. What one has to remember is that private restricts access but not visiblity. The 'package' qualifier has never worked AFAIK. -- Derek Parnell Melbourne, Australia
Jun 18 2006
Derek Parnell wrote:On Sun, 18 Jun 2006 04:15:11 +1000, Chris Miller <chris dprogramming.com> wrote:How is anyone new to D supposed to even consider using it when stuff like _private_ and _package_ are broken???????????????????????? This is both *elementary* and *essential* to any nontrivial project. It simply *has* to work. "Would you buy a 3-wheel Ferrari?" The first guys we lose this way are those who were considering D for real work (as opposed to hobby or tinkering).DMD 0.160: foo.d(1): import foo.std conflicts with bar.std at bar.d(1) Of course, the code in test.d is a mistake, but look how unhelpful the error message is. It will blame a library's code for a mistake the library-user made.Maybe a message more like ... foo.d(6): std.string is not accessible might be more useful for coders.Also notice that it's considering *private* imports, which shouldn't even be available to test.d.This has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't.
Jun 18 2006
Georg Wrede wrote:Derek Parnell wrote:Dig dat, bro' ... Apparently *so* fundamental that there's not even a stress-test for this kind of thingThis has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't.How is anyone new to D supposed to even consider using it when stuff like _private_ and _package_ are broken???????????????????????? This is both *elementary* and *essential* to any nontrivial project. It simply *has* to work. "Would you buy a 3-wheel Ferrari?" The first guys we lose this way are those who were considering D for real work (as opposed to hobby or tinkering).
Jun 18 2006
kris wrote:Georg Wrede wrote:What do you mean? There are lot of testcases in DStress for protection attributes: http://dstress.kuehne.cn/www/dstress.html#private_03 -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DDerek Parnell wrote:Dig dat, bro' ... Apparently *so* fundamental that there's not even a stress-test for this kind of thingThis has been broken for a *long* time now. Both "private" and "package" are just ignored by DMD for at least the last 5 or 6 releases. It used to work but now it doesn't.How is anyone new to D supposed to even consider using it when stuff like _private_ and _package_ are broken???????????????????????? This is both *elementary* and *essential* to any nontrivial project. It simply *has* to work. "Would you buy a 3-wheel Ferrari?" The first guys we lose this way are those who were considering D for real work (as opposed to hobby or tinkering).
Jun 19 2006
Chris Miller wrote:Here's a simple example of the issue: // -- foo.d -- private import std.stdio; // -- bar.d -- private import std.stdio; // -- test.d -- import foo, bar; void main() { char[] hi = std.string.toString(3); } DMD 0.160: foo.d(1): import foo.std conflicts with bar.std at bar.d(1) Of course, the code in test.d is a mistake, but look how unhelpful the error message is. It will blame a library's code for a mistake the library-user made. Also notice that it's considering *private* imports, which shouldn't even be available to test.d.It's considering private imports because of bug 48, but this issue is not the same as bug 48, it is a separate bug, because it also happens with public imports. Submitted as bug 209. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 19 2006
Dawid Ciężarkiewicz wrote:You write your great soft in D. You're coding with smile because everything in seems to be so good. You added few new files, new classes. Porting your project from C++ to D seems to be so good idea. You type "make". And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29)For what it's worth, the symbol resolution rules styled after the C++ class-scope rules. On the surface, this does seem to provide solid support for the approach: it's a sticky issue and an established language has solved the problem this way, so why not do that? However, I think the reasons that this rule was chosen for C++ may be related to language syntax that D simply doesn't have, thus reducing the strength of the correlation. I decided to go looking for information on why the C++ rules are the way they are, and oddly enough the first hit was the C++ Module proposal (available here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1964.pdf) Section 4.3 reads thus: 4.3 Shielding from private members The fact that private members are inaccessible but not invisible regularly surprises incidental programmers. Like macros, seemingly unrelated declarations interfere with subsequent code. Unfortunately, there are good reasons for this state of affair: Without it, private out-of-class member declarations become impractical to parse in the general case. Module namespaces appear to be an ideal boundary for making the private member fully invisible: Within the module the implementer has full control over naming conventions and can therefore easily avoid interference, while outside the module the client will never have to implement private members. (Note that this also addresses the concerns of N1602 "Class Scope Using Declarations & private Members" by Francis Glassborow; the extension proposed therein is then no longer needed.) It's worth noting that the issue discussed in the first paragraph: out-of-class declarations, is not supported in D. All members must be declared in class scope. The second paragraph goes on to make an argument for why private symbols should not be considered across modules for lookup resolution. The only issue not addressed is package visibility, but I believe the same approach could be done at the package level as at the module level. After all, there's a file separation either way. I was unable to find older discussions relating why these rules were chosen for C++, but if there are other arguments against the approach which apply to D, either for current or future features, I would love to hear them. The current state of affairs is annoying and somewhat confusing to new users, but I'd prefer an annoying system that works for all corner-cases to a cleaner one that doesn't. Sean
Jun 17 2006
Sean Kelly wrote:Dawid Ciężarkiewicz wrote:I can't figure out what kind of parallel or comparison could be made of symbol resolution with a language that has no structured module system. What would be the analogous case in C++ for the situation mentioned above? What are the C++ class-scope rules? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DYou write your great soft in D. You're coding with smile because everything in seems to be so good. You added few new files, new classes. Porting your project from C++ to D seems to be so good idea. You type "make". And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29)For what it's worth, the symbol resolution rules styled after the C++ class-scope rules. On the surface, this does seem to provide solid support for the approach: it's a sticky issue and an established language has solved the problem this way, so why not do that? However, I think the reasons that this rule was chosen for C++ may be related to language syntax that D simply doesn't have, thus reducing the strength of the correlation.
Jun 18 2006
Bruno Medeiros wrote:Sean Kelly wrote:C++ class member symbol lookup is roughly similar to module-level lookup in D at a conceptual level, so Walter modeled the D lookup rules on this aspect of C++. If you pretend a C++ class is a D module and use multiple inheritance instead of import you'll see identical behavior for symbol lookup. SeanDawid Ciężarkiewicz wrote:I can't figure out what kind of parallel or comparison could be made of symbol resolution with a language that has no structured module system. What would be the analogous case in C++ for the situation mentioned above? What are the C++ class-scope rules?You write your great soft in D. You're coding with smile because everything in seems to be so good. You added few new files, new classes. Porting your project from C++ to D seems to be so good idea. You type "make". And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29)For what it's worth, the symbol resolution rules styled after the C++ class-scope rules. On the surface, this does seem to provide solid support for the approach: it's a sticky issue and an established language has solved the problem this way, so why not do that? However, I think the reasons that this rule was chosen for C++ may be related to language syntax that D simply doesn't have, thus reducing the strength of the correlation.
Jun 18 2006
Dawid Ciężarkiewicz wrote:And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29)OK. After some time I've finally discovered where the problem was and I see that my previous post is not very informative. Instead it gives good look how such "details" can frustrate people. The problem is (if I understand right): When you use identifier which was imported privately by something you imported in current module you get this missleading "import X conficts with Y" instead of info where it happens. battle.d(31) == "private import map"; cell/cell/d(29) == "private import map"; As you can see your IDE will take you to battle.d, line 31 and you'll be confused. You don't know which line of code triggered error. If you are lucky and smart enough, you'll try fixing later errors and find which part of the code triggered this one. If you're not - you'll be siting and screaming knowing not what to do. The good error msg would look like: $file($line): triggered import conflict with X ($X:$Xline) and Y ($Y:$Yline) Where $file($line) is place where compiler found that this two modules are conflicting. This would be quite informative IMO. Another thing is that I do "private import $i" for purpose - I don't want names from module be _anyhow_ visible - not triggering any conflicts.
Jun 17 2006
Dawid Ciężarkiewicz wrote:The good error msg would look like: $file($line): triggered import conflict with X ($X:$Xline) and Y ($Y:$Yline) Where $file($line) is place where compiler found that this two modules are conflicting. This would be quite informative IMO.Yes.Another thing is that I do "private import $i" for purpose - I don't want names from module be _anyhow_ visible - not triggering any conflicts.I think they should be visible enough to trigger a proper error message, when you don't have any public symbols with the same name. But when you do have, the compiler should be able to mask the private ones then. Only if you have at least two public symbols with the same name, a name conflict should appear. -- Jari-Matti
Jun 17 2006
You're write it is awful. A useful error message would make this a hundred times easier. I've also noticed this always happens strictly with phobos, has anyone had these conflicts with their own modules ? In article <e71f1s$31fj$1 digitaldaemon.com>, Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= says...You write your great soft in D. You're coding with smile because everything in seems to be so good. You added few new files, new classes. Porting your project from C++ to D seems to be so good idea. You type "make". And then out of nowhere: BANG!!! battle.d(31): import battle.map conflicts with cell.cell.map at cell/cell.d(29) GAME OVER! You're stuck with this nothing telling you error message. You start wondering what is wrong. Imports probably, but ... why? It takes 15 minutes of frustrating checking your files. You seek help on #D irc channel (nice people BTW) - but they can not help you. They can only tell "It might be that in some unrelated file you are trying to use map without importing map but are importing files that do import map" which is great help but still will require you to spend great amount of time finding this place. Please Walter - fix this. It is sooooooo frustrating and everyone confirms that. It's something that all D people hits once or more.
Jun 17 2006
I hear ya wrote:You're write it is awful. A useful error message would make this a hundred times easier. I've also noticed this always happens strictly with phobos, has anyone had these conflicts with their own modules ?Ummmm yeah... a lot... Walter, please fix it, it will save my hair ;D -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
Jun 17 2006