digitalmars.D - Selective and renamed imports
- Christian Kamm (51/51) Oct 16 2011 Hello fellow import-users,
- Dmitry Olshansky (6/55) Oct 16 2011 Yes, import != add a public alias from given module. Let them be
- Mike Wey (4/15) Oct 16 2011 Yes, this is how i would expect it to work.
- Jesse Phillips (3/45) Oct 16 2011 Yes, this sounds like what is supposed to happen, and addresses some
- Peter Alexander (2/9) Oct 16 2011 Yes, that's definitely how I would expect it to work.
- Jacob Carlborg (4/10) Oct 16 2011 I agree.
- Nick Sabalausky (8/65) Oct 16 2011 Yes, what Christian suggests is what I would expect. Imports should just...
- Timon Gehr (11/17) Oct 16 2011 I agree. The current behavior is just useless, because it is never
- Jonathan M Davis (5/21) Oct 16 2011 That should be identical to
- Christian Kamm (11/16) Oct 17 2011 Yes. But it doesn't merge the symbol either, so if foo.bar is a function
- Kagamin (7/27) Oct 18 2011 afaik currently all imports include symbols into the importing module.
- Christian Kamm (6/14) Oct 18 2011 No, this import does not introduce a new symbol b.z. It just adds a note...
- Fawzi Mohamed (37/37) Oct 19 2011 I think that the treatment of normal and private imports in the patch =
Hello fellow import-users, I've tried to get bug 314 (http://d.puremagic.com/issues/show_bug.cgi?id=314) fixed for a very long time now. There seems to be no progress and I suspect that the reason for it could be that Walter is unsure whether the import behavior I implemented in https://github.com/D-Programming-Language/dmd/pull/190 is desirable. In this post I'll point out the controversy with selective imports and hope it'll spark some discussion. First off, I think everyone agrees that this test case needs to start passing: base.d -- int foo(int) { return 0; } first.d -- import base : foo; second.d -- import first; static assert(!is(typeof(foo))); It's the baseline for bug 314. No matter how the details are resolved, this needs to work. It's the big "D doesn't even get imports right" hole that makes this bug the most voted for issue on bugzilla. Now, what's the problem? Overload resolution. Currently, selectively importing a function or overload set also *merges it into the local module's overload set*. That has several problems. One is that changing an import to selective or back can change program behavior: overloadproblem.d -- import base; // : foo; long foo(long) { return 0; } static assert(is(typeof(foo(0)) == long)); This code will fail to compile when you change the import to a selective one. The second problem is that, since the base.foo got integrated into the overloadproblem.foo overload set, modules importing 'overloadproblem' are no longer able to honor import visibility: importer.d -- import overloadproblem; static assert(is(typeof(foo(0)) == long)); This will fail even though base.foo was imported privately. To resolve foo(0) to long overloadproblem.foo(long), import visibility would have to be considered during overload resolution to skip int base.foo(int). That's something Walter doesn't want to do. These are the reasons why my pull request changes the selective import behavior to not merge overload sets. It makes 'import base : foo;' treat 'foo' exactly the same way as 'import base;' would have done; it does not matter whether an symbol was imported selectively or not. You can get the old behavior by using an explicit alias. Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, Christian
Oct 16 2011
On 16.10.2011 14:08, Christian Kamm wrote:Hello fellow import-users, I've tried to get bug 314 (http://d.puremagic.com/issues/show_bug.cgi?id=314) fixed for a very long time now. There seems to be no progress and I suspect that the reason for it could be that Walter is unsure whether the import behavior I implemented in https://github.com/D-Programming-Language/dmd/pull/190 is desirable. In this post I'll point out the controversy with selective imports and hope it'll spark some discussion. First off, I think everyone agrees that this test case needs to start passing: base.d -- int foo(int) { return 0; } first.d -- import base : foo; second.d -- import first; static assert(!is(typeof(foo))); It's the baseline for bug 314. No matter how the details are resolved, this needs to work. It's the big "D doesn't even get imports right" hole that makes this bug the most voted for issue on bugzilla. Now, what's the problem? Overload resolution. Currently, selectively importing a function or overload set also *merges it into the local module's overload set*. That has several problems. One is that changing an import to selective or back can change program behavior: overloadproblem.d -- import base; // : foo; long foo(long) { return 0; } static assert(is(typeof(foo(0)) == long)); This code will fail to compile when you change the import to a selective one. The second problem is that, since the base.foo got integrated into the overloadproblem.foo overload set, modules importing 'overloadproblem' are no longer able to honor import visibility: importer.d -- import overloadproblem; static assert(is(typeof(foo(0)) == long)); This will fail even though base.foo was imported privately. To resolve foo(0) to long overloadproblem.foo(long), import visibility would have to be considered during overload resolution to skip int base.foo(int). That's something Walter doesn't want to do. These are the reasons why my pull request changes the selective import behavior to not merge overload sets. It makes 'import base : foo;' treat 'foo' exactly the same way as 'import base;' would have done; it does not matter whether an symbol was imported selectively or not. You can get the old behavior by using an explicit alias. Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course.Yes, import != add a public alias from given module. Let them be consistent. P.S. I'm looking forward to that patch eventually getting merged. -- Dmitry Olshansky
Oct 16 2011
On 10/16/2011 12:08 PM, Christian Kamm wrote:These are the reasons why my pull request changes the selective import behavior to not merge overload sets. It makes 'import base : foo;' treat 'foo' exactly the same way as 'import base;' would have done; it does not matter whether an symbol was imported selectively or not. You can get the old behavior by using an explicit alias. Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianYes, this is how i would expect it to work. -- Mike Wey
Oct 16 2011
On Sun, 16 Oct 2011 12:08:53 +0200, Christian Kamm wrote:Now, what's the problem? Overload resolution. Currently, selectively importing a function or overload set also *merges it into the local module's overload set*. That has several problems. One is that changing an import to selective or back can change program behavior: overloadproblem.d -- import base; // : foo; long foo(long) { return 0; } static assert(is(typeof(foo(0)) == long)); This code will fail to compile when you change the import to a selective one. The second problem is that, since the base.foo got integrated into the overloadproblem.foo overload set, modules importing 'overloadproblem' are no longer able to honor import visibility: importer.d -- import overloadproblem; static assert(is(typeof(foo(0)) == long)); This will fail even though base.foo was imported privately. To resolve foo(0) to long overloadproblem.foo(long), import visibility would have to be considered during overload resolution to skip int base.foo(int). That's something Walter doesn't want to do. These are the reasons why my pull request changes the selective import behavior to not merge overload sets. It makes 'import base : foo;' treat 'foo' exactly the same way as 'import base;' would have done; it does not matter whether an symbol was imported selectively or not. You can get the old behavior by using an explicit alias. Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianYes, this sounds like what is supposed to happen, and addresses some questions that have come up on D.learn.
Oct 16 2011
On 16/10/11 11:08 AM, Christian Kamm wrote:<snip> Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianYes, that's definitely how I would expect it to work.
Oct 16 2011
On 2011-10-16 12:08, Christian Kamm wrote:Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianI agree. -- /Jacob Carlborg
Oct 16 2011
"Christian Kamm" <kamm-incasoftware removethis.de> wrote in message news:j7eahc$30ph$1 digitalmars.com...Hello fellow import-users, I've tried to get bug 314 (http://d.puremagic.com/issues/show_bug.cgi?id=314) fixed for a very long time now. There seems to be no progress and I suspect that the reason for it could be that Walter is unsure whether the import behavior I implemented in https://github.com/D-Programming-Language/dmd/pull/190 is desirable. In this post I'll point out the controversy with selective imports and hope it'll spark some discussion. First off, I think everyone agrees that this test case needs to start passing: base.d -- int foo(int) { return 0; } first.d -- import base : foo; second.d -- import first; static assert(!is(typeof(foo))); It's the baseline for bug 314. No matter how the details are resolved, this needs to work. It's the big "D doesn't even get imports right" hole that makes this bug the most voted for issue on bugzilla. Now, what's the problem? Overload resolution. Currently, selectively importing a function or overload set also *merges it into the local module's overload set*. That has several problems. One is that changing an import to selective or back can change program behavior: overloadproblem.d -- import base; // : foo; long foo(long) { return 0; } static assert(is(typeof(foo(0)) == long)); This code will fail to compile when you change the import to a selective one. The second problem is that, since the base.foo got integrated into the overloadproblem.foo overload set, modules importing 'overloadproblem' are no longer able to honor import visibility: importer.d -- import overloadproblem; static assert(is(typeof(foo(0)) == long)); This will fail even though base.foo was imported privately. To resolve foo(0) to long overloadproblem.foo(long), import visibility would have to be considered during overload resolution to skip int base.foo(int). That's something Walter doesn't want to do. These are the reasons why my pull request changes the selective import behavior to not merge overload sets. It makes 'import base : foo;' treat 'foo' exactly the same way as 'import base;' would have done; it does not matter whether an symbol was imported selectively or not. You can get the old behavior by using an explicit alias. Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course.Yes, what Christian suggests is what I would expect. Imports should just be imports, whether selective or otherwise. Actually merging symbols into the current module is the job of alias, and if that's the behavior I wanted, than that's what I would have used: alias. If *certain* imports (ie, selective) are invading alias's territory, I'd classify that as either a bug or a design error.
Oct 16 2011
On 10/16/2011 12:08 PM, Christian Kamm wrote:Does this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianI agree. The current behavior is just useless, because it is never desirable or even acceptable to have implementation details leak into the public interface. Currently not even private import foo : bar; hides bar iirc. The sooner this gets merged the less code that inadvertently depends on undocumented symbols gets broken. Does public import foo : bar; work as expected with your pull request?
Oct 16 2011
On Monday, October 17, 2011 00:17:56 Timon Gehr wrote:On 10/16/2011 12:08 PM, Christian Kamm wrote:That should be identical to import foo : bar; so if it one hid it and one didn't, that would _still_ be a problem. - Jonathan M DavisDoes this work as you'd expect? Please write a short reply even if you just agree. I hope the feedback will convince Walter to give this serious consideration. You can also let me know that this is totally bananas, of course. Regards, ChristianI agree. The current behavior is just useless, because it is never desirable or even acceptable to have implementation details leak into the public interface. Currently not even private import foo : bar; hides bar iirc.
Oct 16 2011
Timon Gehr wrote:Does public import foo : bar; work as expected with your pull request?Yes. But it doesn't merge the symbol either, so if foo.bar is a function a.d -- public import foo : bar; void bar() {} b.d -- import a; // will only see the bar defined in a.d. Maybe public selective imports should actually behave the same way as aliases? Alternatively it could be an error: "'bar' hides publicly imported symbol of the same name"
Oct 17 2011
Christian Kamm Wrote:Timon Gehr wrote:afaik currently all imports include symbols into the importing module. --- a.d --- int z; --- b.d --- import a; a.z is available as b.z now.Does public import foo : bar; work as expected with your pull request?Yes. But it doesn't merge the symbol either, so if foo.bar is a function a.d -- public import foo : bar; void bar() {} b.d -- import a; // will only see the bar defined in a.d. Maybe public selective imports should actually behave the same way as aliases? Alternatively it could be an error: "'bar' hides publicly imported symbol of the same name"
Oct 18 2011
Kagamin wrote:afaik currently all imports include symbols into the importing module. --- a.d --- int z; --- b.d --- import a; a.z is available as b.z now.No, this import does not introduce a new symbol b.z. It just adds a note to b's root scope saying "if a symbol isn't found here, check in a". It works differently for selective imports and that's cause for the problems with them: If you had done 'import a : z;' there would actually be a new symbol b.z.
Oct 18 2011
I think that the treatment of normal and private imports in the patch = proposed is the correct one. Importing should be hidden, this is also basically what LDC 1 does, as = it is much more strict on indirect imports. Public imports on the other hand should be roughly equivalent to = declaring the things in the module the imports them. To be more precise they should be *exactly* equivalent to a private = import + alias for all the imported things. Being selective or renaming in my opinion should not be connected with = outside visibility, that should be controlled with public/private. There is indeed a difference between import and selective or renamed = imports, and plain full module imports. Those are imported with the goal of being used, thus one should check = for collisions. The solution is to make import x: y, a=3Dz; public import m1; public import m2: t, t2=3Dr; which is equivalent to private import x: y, a=3Dz; public import m1; public import m2: t, t2=3Dr; equivalent to import x; private alias x.y y; private alias x.z a; import m1; public alias m1.* *; // this is a shortcut to mean public = aliases to all things declared in m1 import m2; public alias m2.t t; public alias m2.r t2; and privately exported symbols should never be visible when imported = again. I think that this is a semantic that makes sense, and looks natural, and = piggybacks on already defined concepts. Fawzi=
Oct 19 2011