digitalmars.D - Nested public imports - bug or feature?
- Dicebot (14/14) Aug 13 2015 Right now this works:
- Jonathan M Davis (17/31) Aug 13 2015 Well, that's pretty much why splitting up a module and putting
- Timon Gehr (17/50) Aug 13 2015 It has nothing to do with the import being public. This works:
- Dmitry Olshansky (5/24) Aug 13 2015 Agreed, public import case looks legitimate.
- Dicebot (4/19) Aug 13 2015 Ah, I thought alias injection is only done for public ones. Same
- Timon Gehr (4/9) Aug 13 2015 If there is only one sane/consistent/turtles/etc choice for the
- Dicebot (5/11) Aug 13 2015 It won't work if you define importing as adding module to
- Timon Gehr (4/12) Aug 13 2015 It's about _public_ imports, which are special. (Also, you don't need to...
- rsw0x (2/16) Aug 13 2015 And we're back to namespaces : )
- Dicebot (27/28) Aug 13 2015 Not really.
- Timon Gehr (3/31) Aug 13 2015 What's the alternative?
- Dicebot (16/19) Aug 13 2015 Yes, as well as about renamed and selective ones ;)
- Timon Gehr (5/25) Aug 13 2015 (Which is an arbitrary restriction most likely motivated by
- Dicebot (4/15) Aug 13 2015 Well I prefer to work with tools I have right now and not wait
- Timon Gehr (4/39) Aug 13 2015 (It's about communicating clearly what the problem actually is. static
- Dicebot (8/15) Aug 13 2015 Relevant as explanation why I don't consider aliased imports a
- Timon Gehr (29/51) Aug 13 2015 I am unable to understand your concerns precisely, because you are
- Dicebot (15/15) Aug 14 2015 Ok, let's stop for a minute and make sure we are on the same
- Timon Gehr (8/24) Aug 14 2015 OK. This is my view: The sub-thread was started with the claim that the
- Dicebot (11/26) Aug 15 2015 I called it broken because it makes impossible to add new symbols
- Timon Gehr (5/32) Aug 15 2015 Sure, but I think the disagreement is on what it /means/ for a module
- Jonathan M Davis (23/44) Aug 13 2015 You can get that behavior with static imports in D, but having to
- Dicebot (8/11) Aug 13 2015 Check example again, you are only required to use the plain
- Timon Gehr (3/12) Aug 13 2015 static import std.stdio;
- Jonathan M Davis (7/18) Aug 13 2015 Well, that's better than requiring the full import path, but
- Dicebot (7/13) Aug 13 2015 Matter of scale. At some point of application size maintenance
- Jonathan M Davis (12/27) Aug 13 2015 Well, if name clashes become that high in a .cpp file, odds are
- Dicebot (7/13) Aug 13 2015 My projects have been broken twice by adding new functions to
- Jonathan M Davis (8/22) Aug 13 2015 Yes. Clashes are going to happen, especially if you're using
- Dmitry Olshansky (6/28) Aug 13 2015 Because private symbols from imported modules *do* clash with public
- Jonathan M Davis (15/48) Aug 13 2015 Oh. That makes the problem even worse, and it definitely needs to
- Meta (4/7) Aug 13 2015 It's worse than embarassing. Every symbol added, public or
- jmh530 (18/23) Aug 13 2015 I would add that it's not just C++. It is also common in Python
- Dejan Lekic (6/17) Aug 14 2015 Thank God, D does it the "not good" way. But I guess that is
- Timon Gehr (6/24) Aug 14 2015 Rust supports both. D supports both. I still fail to see how one
- anonymous (2/7) Aug 13 2015 What's wrong with `import Something = a;`? Bugs?
- Kagamin (2/2) Aug 13 2015 As long as imports are not hygienic, this trick is useful. I
- Walter Bright (6/20) Aug 19 2015 It has nothing to do with aliases.
- Timon Gehr (4/11) Aug 19 2015 This is exactly the right way to do it.
Right now this works: ``D struct Std { public import std.stdio; } void main() { Std.writeln("Nice!"); } ``` I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).
Aug 13 2015
On Thursday, 13 August 2015 at 13:12:44 UTC, Dicebot wrote:Right now this works: ``D struct Std { public import std.stdio; } void main() { Std.writeln("Nice!"); } ``` I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).Well, that's pretty much why splitting up a module and putting public imports in its package.d file doesn't break any of the cases where someone types out the full import path when referring to something from that module/package. But I doubt that anyone considered that that would have this effect when you have a scoped import. In fact, to be honest, it never occurred to me that it would be legal to have a scoped, public import. I think that you just hit a weird result of how allowing imports to be put everywhere ended up working. I confess that I don't particularly like that this is legal (and I think that public imports tend to get a bit hinky because of the fact that they create aliases), and I'm not quite sure how you could use it form "import hygiene," but I also don't see how this could work any other way if scoped, public imports are allowed. - Jonathan M Davis
Aug 13 2015
On 08/13/2015 03:42 PM, Jonathan M Davis wrote:On Thursday, 13 August 2015 at 13:12:44 UTC, Dicebot wrote:It has nothing to do with the import being public. This works: --- struct Std{ import std.stdio; } void main(){ Std.writeln("Nice!"); } --- (It also works if main and Std are defined in different modules.)Right now this works: ``D struct Std { public import std.stdio; } void main() { Std.writeln("Nice!"); } ``` I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).Well, that's pretty much why splitting up a module and putting public imports in its package.d file doesn't break any of the cases where someone types out the full import path when referring to something from that module/package. But I doubt that anyone considered that that would have this effect when you have a scoped import. In fact, to be honest, it never occurred to me that it would be legal to have a scoped, public import. I think that you just hit a weird result of how allowing imports to be put everywhere ended up working. I confess that I don't particularly like that this is legal (and I think that public imports tend to get a bit hinky because of the fact that they create aliases), and I'm not quite sure how you could use it form "import hygiene,"but I also don't see how this could work any other way if scoped, public imports are allowed. ...Easy. Just treat aggregate scopes and module scopes differently. (They are treated differently even now: all imports are 'public' in aggregate scopes, but not at module scope.) I think this shouldn't be done though. In any case, I guess we agree that this idiom should work for public imports, but not for non-public ones (so the current behaviour with non-public imports is accepts-invalid, but Dicebot's code should be fine)?
Aug 13 2015
On 13-Aug-2015 16:56, Timon Gehr wrote: [snip]It has nothing to do with the import being public. This works: --- struct Std{ import std.stdio; } void main(){ Std.writeln("Nice!"); } --- (It also works if main and Std are defined in different modules.)Agreed, public import case looks legitimate. -- Dmitry Olshanskybut I also don't see how this could work any other way if scoped, public imports are allowed. ...Easy. Just treat aggregate scopes and module scopes differently. (They are treated differently even now: all imports are 'public' in aggregate scopes, but not at module scope.) I think this shouldn't be done though. In any case, I guess we agree that this idiom should work for public imports, but not for non-public ones (so the current behaviour with non-public imports is accepts-invalid, but Dicebot's code should be fine)?
Aug 13 2015
On Thursday, 13 August 2015 at 13:56:24 UTC, Timon Gehr wrote:It has nothing to do with the import being public. This works: --- struct Std{ import std.stdio; } void main(){ Std.writeln("Nice!"); } --- (It also works if main and Std are defined in different modules.)Ah, I thought alias injection is only done for public ones. Same question applies though :)In any case, I guess we agree that this idiom should work for public imports, but not for non-public ones (so the current behaviour with non-public imports is accepts-invalid, but Dicebot's code should be fine)?I am very curious to learn "official" answer :)
Aug 13 2015
On 08/13/2015 05:34 PM, Dicebot wrote:If there is only one sane/consistent/turtles/etc choice for the behaviour of some feature, typically, assuming that /eventually/ this choice will be made works.In any case, I guess we agree that this idiom should work for public imports, but not for non-public ones (so the current behaviour with non-public imports is accepts-invalid, but Dicebot's code should be fine)?I am very curious to learn "official" answer :)
Aug 13 2015
On Thursday, 13 August 2015 at 13:42:42 UTC, Jonathan M Davis wrote:I confess that I don't particularly like that this is legal (and I think that public imports tend to get a bit hinky because of the fact that they create aliases), and I'm not quite sure how you could use it form "import hygiene," but I also don't see how this could work any other way if scoped, public imports are allowed.It won't work if you define importing as adding module to internal scope symbol lookup table, without actually adding imported symbols to scope.
Aug 13 2015
On 08/13/2015 05:35 PM, Dicebot wrote:On Thursday, 13 August 2015 at 13:42:42 UTC, Jonathan M Davis wrote:It's about _public_ imports, which are special. (Also, you don't need to "actually" add imported symbols to any scope. The "redirect" method also works for '.' access.)I confess that I don't particularly like that this is legal (and I think that public imports tend to get a bit hinky because of the fact that they create aliases), and I'm not quite sure how you could use it form "import hygiene," but I also don't see how this could work any other way if scoped, public imports are allowed.It won't work if you define importing as adding module to internal scope symbol lookup table, without actually adding imported symbols to scope.
Aug 13 2015
On Thursday, 13 August 2015 at 13:12:44 UTC, Dicebot wrote:Right now this works: ``D struct Std { public import std.stdio; } void main() { Std.writeln("Nice!"); } ``` I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).And we're back to namespaces : )
Aug 13 2015
On Thursday, 13 August 2015 at 13:44:50 UTC, rsw0x wrote:And we're back to namespaces : )Not really. This is namespace: ----- module a; struct Something { static void foo() {} } module b; import a; void main() { Something.foo(); } ----- This is import hygiene: ----- module a; void foo() { } module b; struct Something { public import a; } void main() { Something.foo(); } ----- Without that you risk breaking the code each time you add new symbol to a library - D module system is completely broken in that regard.
Aug 13 2015
On 08/13/2015 05:29 PM, Dicebot wrote:On Thursday, 13 August 2015 at 13:44:50 UTC, rsw0x wrote:You know about static imports, right?And we're back to namespaces : )Not really. This is namespace: ----- module a; struct Something { static void foo() {} } module b; import a; void main() { Something.foo(); } ----- This is import hygiene: ----- module a; void foo() { } module b; struct Something { public import a; } void main() { Something.foo(); } ----- Without that you risk breaking the code each time you add new symbol to a library -D module system is completely broken in that regard.What's the alternative?
Aug 13 2015
On Thursday, 13 August 2015 at 15:40:12 UTC, Timon Gehr wrote:You know about static imports, right?Yes, as well as about renamed and selective ones ;) Problem with static imports is that they are all-or-nothing. And in our projects it is common to have module names with 5 nested packages or even more. Typing all of it is impractical - simple prefix gives enough protection from random clashes.When doing my old "Rust vs D" comparison I have been mentioning their import semantics as a big win. When you do import like this: use phrases::english::greetings; You must always also qualify symbol name with module name like this: println!("Hello in English: {}", greetings::hello()); And this won't compile: println!("Hello in English: {}", hello()); It has similar benefits as the idiom proposed in this topic - greatly reduced risk of accidental clashes.D module system is completely broken in that regard.What's the alternative?
Aug 13 2015
On 08/13/2015 05:49 PM, Dicebot wrote:On Thursday, 13 August 2015 at 15:40:12 UTC, Timon Gehr wrote:(Which is an arbitrary restriction most likely motivated by implementation difficulties.)You know about static imports, right?Yes, as well as about renamed and selective ones ;) Problem with static imports is that they are all-or-nothing.And in our projects it is common to have module names with 5 nested packages or even more. Typing all of it is impractical - simple prefix gives enough protection from random clashes.static import greetings=phrases.english.greetings; ?When doing my old "Rust vs D" comparison I have been mentioning their import semantics as a big win. When you do import like this: use phrases::english::greetings; You must always also qualify symbol name with module name like this: println!("Hello in English: {}", greetings::hello()); And this won't compile: println!("Hello in English: {}", hello()); It has similar benefits as the idiom proposed in this topic - greatly reduced risk of accidental clashes.D module system is completely broken in that regard.What's the alternative?
Aug 13 2015
On Thursday, 13 August 2015 at 15:59:46 UTC, Timon Gehr wrote:On 08/13/2015 05:49 PM, Dicebot wrote:Well I prefer to work with tools I have right now and not wait for something sane to be implemented.On Thursday, 13 August 2015 at 15:40:12 UTC, Timon Gehr wrote:(Which is an arbitrary restriction most likely motivated by implementation difficulties.)You know about static imports, right?Yes, as well as about renamed and selective ones ;) Problem with static imports is that they are all-or-nothing.static import greetings=phrases.english.greetings; ?http://forum.dlang.org/post/szaaakmavraxatkrfpnx forum.dlang.org
Aug 13 2015
On 08/13/2015 06:19 PM, Dicebot wrote:On Thursday, 13 August 2015 at 15:59:46 UTC, Timon Gehr wrote:(It's about communicating clearly what the problem actually is. static imports are not inherently all-or-nothing.)On 08/13/2015 05:49 PM, Dicebot wrote:Well I prefer to work with tools I have right now and not wait for something sane to be implemented. ...On Thursday, 13 August 2015 at 15:40:12 UTC, Timon Gehr wrote:(Which is an arbitrary restriction most likely motivated by implementation difficulties.)You know about static imports, right?Yes, as well as about renamed and selective ones ;) Problem with static imports is that they are all-or-nothing.How is this relevant? Does Rust support it?http://forum.dlang.org/post/szaaakmavraxatkrfpnx forum.dlang.orgWhen doing my old "Rust vs D" comparison I have been mentioning their import semantics as a big win. When you do import like this: use phrases::english::greetings; You must always also qualify symbol name with module name like this: println!("Hello in English: {}", greetings::hello()); And this won't compile: println!("Hello in English: {}", hello()); It has similar benefits as the idiom proposed in this topic - greatly reduced risk of accidental clashes.static import greetings=phrases.english.greetings; ?
Aug 13 2015
On Thursday, 13 August 2015 at 16:24:56 UTC, Timon Gehr wrote:Relevant as explanation why I don't consider aliased imports a solution. Rust does exactly that and I feel that "bottom-qualification" is inferior approach to "top-qualification" in general for deeply nested package hierarchies. Of course, both are much more hygienic than semantics D uses by default - yet if I am forced to resort to idioms, I want to get most out of it :)How is this relevant? Does Rust support it?static import greetings=phrases.english.greetings; ?http://forum.dlang.org/post/szaaakmavraxatkrfpnx forum.dlang.org
Aug 13 2015
On 08/13/2015 06:36 PM, Dicebot wrote:On Thursday, 13 August 2015 at 16:24:56 UTC, Timon Gehr wrote:I am unable to understand your concerns precisely, because you are making up words without giving definitions or examples. https://www.google.ch/search?q=module+system+bottom-qualification https://www.google.ch/search?q=module+system+top-qualification https://www.google.ch/search?q=define+hygienic+module+systemRelevant as explanation why I don't consider aliased imports a solution. Rust does exactly that and I feel that "bottom-qualification" is inferior approach to "top-qualification" in general for deeply nested package hierarchies. Of course, both are much more hygienic than semantics D uses by defaultHow is this relevant? Does Rust support it?static import greetings=phrases.english.greetings; ?http://forum.dlang.org/post/szaaakmavraxatkrfpnx forum.dlang.org- yet if I am forced to resort to idioms, I want to get most out of it :)This was the example given in that post:import mypkg = mypkg.mysubpkg.mod1; import mypkg = mypkg.mysubpkg.mod2; // error, can't redefine aliased import! struct mypkg { import mypkg.mysubpkg.mod1; import mypkg.mysubpkg.mod2; // fine }FWIW: --- use mypkg::mysubpkg::mod1 as myuse; use mypkg::mysubpkg::mod2 as myuse; --- error: a module named `myuse` has already been imported in this module [E0252] use mypkg::mysubpkg::mod2 as myuse; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You have to resort to the following idiom: mod myuse{ pub use mypkg::mysubpkg::mod1::*; pub use mypkg::mysubpkg::mod2::*; } Now, note: if there is any identifier `foo' which is exported by both `mod1' and `mod2', then the Rust compiler will error out eagerly here, even if `myuse::foo' never occurs in the code. How is this superior? AFAICS, the only other major semantic difference which would make Rust's system vastly superior is given by the situation that DMD comically thinks private symbols have a reason to cause conflicts in other modules. Was this your "hygiene" point?
Aug 13 2015
Ok, let's stop for a minute and make sure we are on the same thread here. Because you seem to argue something I have never said or at least intended to say. So, my basic statements: 1. I don't like default D import semantics but I am not proposing to change it 2. I like Rust default import semantics (requiring module name) more than default D one. It is possible to emulate it by turning every single import into aliased import. 3. Idiom proposed in the first post is based on similar reasoning as Rust behavior but is different in functionality (one I find even more practical personally). 4. Both feel more practical to me than default D behavior and both require custom idioms/conventions in D Does that make sense?
Aug 14 2015
On 08/14/2015 08:57 PM, Dicebot wrote:Ok, let's stop for a minute and make sure we are on the same thread here. Because you seem to argue something I have never said or at least intended to say. ...OK. This is my view: The sub-thread was started with the claim that the module system is "completely broken" in a particular way. You gave Rust's system as an alternative, but it is (basically) the same thing with slightly different syntax.So, my basic statements: 1. I don't like default D import semantics but I am not proposing to change it 2. I like Rust default import semantics (requiring module name) more than default D one. It is possible to emulate it by turning every single import into aliased import. 3. Idiom proposed in the first post is based on similar reasoning as Rust behavior but is different in functionality (one I find even more practical personally). 4. Both feel more practical to me than default D behavior and both require custom idioms/conventions in D Does that make sense?Not really. It is up to the programmer which of the idioms to use by default, and all options exist in both languages. It's not that important, I guess.
Aug 14 2015
On Friday, 14 August 2015 at 20:12:43 UTC, Timon Gehr wrote:On 08/14/2015 08:57 PM, Dicebot wrote:I called it broken because it makes impossible to add new symbols to the library without possibly breaking user code. Same scenario in Rust is much less likely - comparing default import semantics, of course. And idioms don't matter because only very few use them, thus I only consider default import behaviour when making such statement. Still disagree?Ok, let's stop for a minute and make sure we are on the same thread here. Because you seem to argue something I have never said or at least intended to say. ...OK. This is my view: The sub-thread was started with the claim that the module system is "completely broken" in a particular way. You gave Rust's system as an alternative, but it is (basically) the same thing with slightly different syntax.Won't try to convince anyone about good style and stuff. All I need is some confirmation that presented nested import semantics will stay :( Will try poking Walter personally.Does that make sense?Not really. It is up to the programmer which of the idioms to use by default, and all options exist in both languages. It's not that important, I guess.
Aug 15 2015
On 08/15/2015 06:15 PM, Dicebot wrote:On Friday, 14 August 2015 at 20:12:43 UTC, Timon Gehr wrote:Sure, but I think the disagreement is on what it /means/ for a module system to be broken, hence it is not actually important. Thanks!On 08/14/2015 08:57 PM, Dicebot wrote:I called it broken because it makes impossible to add new symbols to the library without possibly breaking user code. Same scenario in Rust is much less likely - comparing default import semantics, of course. And idioms don't matter because only very few use them, thus I only consider default import behaviour when making such statement. Still disagree? ...Ok, let's stop for a minute and make sure we are on the same thread here. Because you seem to argue something I have never said or at least intended to say. ...OK. This is my view: The sub-thread was started with the claim that the module system is "completely broken" in a particular way. You gave Rust's system as an alternative, but it is (basically) the same thing with slightly different syntax.Ok. Still "yes" is the only answer that makes any sense, and breaking legitimate D code is not among Walter's priorities. :-)Won't try to convince anyone about good style and stuff. All I need is some confirmation that presented nested import semantics will stay :( Will try poking Walter personally.Does that make sense?Not really. It is up to the programmer which of the idioms to use by default, and all options exist in both languages. It's not that important, I guess.
Aug 15 2015
On Thursday, 13 August 2015 at 15:49:10 UTC, Dicebot wrote:On Thursday, 13 August 2015 at 15:40:12 UTC, Timon Gehr wrote:You can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast. There's a reason that using directives get used heavily in C++, though at least there, if you're behaving yourself and not using using directives in .h files, that doesn't affect #includes, unlike with D's import (though having to fully qualify everything in header files is always annoying). But you still end up with potential breakage in .cpp files due to new symbols being introduced which clash. I honestly don't see a good solution to the problem, because requiring that you fully qualify symbols is incredibly annoying and hideous, but if you don't, then adding symbols to a module is always going to break code. As far as I can tell, your module system is stuck with one poison or the other. Maybe something similar to using directives that didn't leak outside of the module would be a reasonable compromise, but then many folks would just have a using directive for every import in order to avoid having to fully qualify symbols. So, I really don't see a good solution, and while the potential breakage caused by D's solution is annoying, I'd much rather have that then be forced to use fully qualified names. - Jonathan M DavisYou know about static imports, right?Yes, as well as about renamed and selective ones ;) Problem with static imports is that they are all-or-nothing. And in our projects it is common to have module names with 5 nested packages or even more. Typing all of it is impractical - simple prefix gives enough protection from random clashes.When doing my old "Rust vs D" comparison I have been mentioning their import semantics as a big win. When you do import like this: use phrases::english::greetings; You must always also qualify symbol name with module name like this: println!("Hello in English: {}", greetings::hello()); And this won't compile: println!("Hello in English: {}", hello()); It has similar benefits as the idiom proposed in this topic - greatly reduced risk of accidental clashes.D module system is completely broken in that regard.What's the alternative?
Aug 13 2015
On Thursday, 13 August 2015 at 16:19:29 UTC, Jonathan M Davis wrote:You can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast.Check example again, you are only required to use the plain module name, not fully qualified one. With D syntax: import std.stdio; writeln(); // not good stdio.writeln(); // good std.stdio.writeln(); // also good, but not required
Aug 13 2015
On 08/13/2015 06:22 PM, Dicebot wrote:On Thursday, 13 August 2015 at 16:19:29 UTC, Jonathan M Davis wrote:static import std.stdio; private alias stdio=std.stdio;You can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast.Check example again, you are only required to use the plain module name, not fully qualified one. With D syntax: import std.stdio; writeln(); // not good stdio.writeln(); // good std.stdio.writeln(); // also good, but not required
Aug 13 2015
On Thursday, 13 August 2015 at 16:22:04 UTC, Dicebot wrote:On Thursday, 13 August 2015 at 16:19:29 UTC, Jonathan M Davis wrote:Well, that's better than requiring the full import path, but requiring _any_ module name is just plain annoying IMHO. If I were okay with that I wouldn't be doing stuff like using namespace std; in all of my .cpp files - and that's a really common thing to do. - Jonathan M DavisYou can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast.Check example again, you are only required to use the plain module name, not fully qualified one. With D syntax: import std.stdio; writeln(); // not good stdio.writeln(); // good std.stdio.writeln(); // also good, but not required
Aug 13 2015
On Thursday, 13 August 2015 at 16:37:00 UTC, Jonathan M Davis wrote:Well, that's better than requiring the full import path, but requiring _any_ module name is just plain annoying IMHO. If I were okay with that I wouldn't be doing stuff like using namespace std; in all of my .cpp files - and that's a really common thing to do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance. In my C++ projects such "using" abuse was normally banned.
Aug 13 2015
On Thursday, 13 August 2015 at 16:40:31 UTC, Dicebot wrote:On Thursday, 13 August 2015 at 16:37:00 UTC, Jonathan M Davis wrote:Well, if name clashes become that high in a .cpp file, odds are that it's pulling in too much stuff.Well, that's better than requiring the full import path, but requiring _any_ module name is just plain annoying IMHO. If I were okay with that I wouldn't be doing stuff like using namespace std; in all of my .cpp files - and that's a really common thing to do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance.In my C++ projects such "using" abuse was normally banned.I've never worked on a team that banned them. Every C++ project that I've ever worked on has used them heavily. It's common practice for every namespace that's being used in a .cpp file to having a corresponding using directive. On the rare cases where there's a collision, you then have to be more explicit, but I've never seen it be much of a problem - and definitely nowhere near enough of a problem to consider banning using directives. I'd _hate_ to be writing code that required being that explicit. - Jonathan M Davis
Aug 13 2015
On Thursday, 13 August 2015 at 17:06:18 UTC, Jonathan M Davis wrote:My projects have been broken twice by adding new functions to druntime (and one was symbol added to object.di :)). Forgive me if I discard that argument as nonsense. If short names are allowed and project is big enough, clashes are simply inevitable. With D module system even medium size will do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance.Well, if name clashes become that high in a .cpp file, odds are that it's pulling in too much stuff.
Aug 13 2015
On Thursday, 13 August 2015 at 17:09:11 UTC, Dicebot wrote:On Thursday, 13 August 2015 at 17:06:18 UTC, Jonathan M Davis wrote:Yes. Clashes are going to happen, especially if you're using short names heavily, but in C++, I've rarely had problems with it. D is potentially worse, because we don't have the equivalent separation of header and source files where it's only the source files that risk breakage. But still, I'd _much_ rather just deal with the occasional breakage than have to qualify everything. - Jonathan M DavisMy projects have been broken twice by adding new functions to druntime (and one was symbol added to object.di :)). Forgive me if I discard that argument as nonsense. If short names are allowed and project is big enough, clashes are simply inevitable. With D module system even medium size will do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance.Well, if name clashes become that high in a .cpp file, odds are that it's pulling in too much stuff.
Aug 13 2015
On 13-Aug-2015 20:17, Jonathan M Davis wrote:On Thursday, 13 August 2015 at 17:09:11 UTC, Dicebot wrote:Because private symbols from imported modules *do* clash with public ones even though not accessible. THAT is the problem and header/source is not the reason of D doing worse here.On Thursday, 13 August 2015 at 17:06:18 UTC, Jonathan M Davis wrote:Yes. Clashes are going to happen, especially if you're using short names heavily, but in C++, I've rarely had problems with it. D is potentially worse,My projects have been broken twice by adding new functions to druntime (and one was symbol added to object.di :)). Forgive me if I discard that argument as nonsense. If short names are allowed and project is big enough, clashes are simply inevitable. With D module system even medium size will do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance.Well, if name clashes become that high in a .cpp file, odds are that it's pulling in too much stuff.because we don't have the equivalent separation of header and source files where it's only the source files that risk breakage. But still, I'd _much_ rather just deal with the occasional breakage than have to qualify everything. - Jonathan M Davis-- Dmitry Olshansky
Aug 13 2015
On Thursday, 13 August 2015 at 17:32:33 UTC, Dmitry Olshansky wrote:On 13-Aug-2015 20:17, Jonathan M Davis wrote:Oh. That makes the problem even worse, and it definitely needs to be fixed, but the fact that you're essentially forced to use fully qualified names in C++ for header files means that you're not going to run into name clashes in the public declarations - only in the function bodies in the .cpp file - whereas all of that is out in the open with .d files. So, the header/source separation does reduce the problem in C++, and even if we do fix the private symbol mess in D, D will still have more name clashing problems because it doesn't normally have that separation. But the private symbols affecting the public API is just plain embarrassing and definitely makes the problem _far_ worse. - Jonathan M DavisOn Thursday, 13 August 2015 at 17:09:11 UTC, Dicebot wrote:Because private symbols from imported modules *do* clash with public ones even though not accessible. THAT is the problem and header/source is not the reason of D doing worse here.On Thursday, 13 August 2015 at 17:06:18 UTC, Jonathan M Davis wrote:Yes. Clashes are going to happen, especially if you're using short names heavily, but in C++, I've rarely had problems with it. D is potentially worse,My projects have been broken twice by adding new functions to druntime (and one was symbol added to object.di :)). Forgive me if I discard that argument as nonsense. If short names are allowed and project is big enough, clashes are simply inevitable. With D module system even medium size will do.Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance.Well, if name clashes become that high in a .cpp file, odds are that it's pulling in too much stuff.
Aug 13 2015
On Thursday, 13 August 2015 at 17:51:06 UTC, Jonathan M Davis wrote:But the private symbols affecting the public API is just plain embarrassing and definitely makes the problem _far_ worse. - Jonathan M DavisIt's worse than embarassing. Every symbol added, public or private, must be considered a breaking change.
Aug 13 2015
On Thursday, 13 August 2015 at 16:40:31 UTC, Dicebot wrote:Matter of scale. At some point of application size maintenance cost become much higher than development costs - and problems of name clashes become more important than any extra typing annoyance. In my C++ projects such "using" abuse was normally banned.I would add that it's not just C++. It is also common in Python to use the full name, albeit typically with an alias, e.g. import numpy as np. One benefit of this approach is that you can easily find every function using numpy in a file. So, while I'm sympathetic with Jonathan's point about requiring the module being a little annoying if you're doing something small, I think you raise a good point about large projects. Nevertheless, others have already pointed out options for allowing the control that you need. If you think that you should be able to re-define imports, then submit an enhancement request. I looked for any suggesting it, but didn't see anything. I did see a few others related to imports that were interesting like allowing something like import std { array, range; }
Aug 13 2015
On Thursday, 13 August 2015 at 16:22:04 UTC, Dicebot wrote:On Thursday, 13 August 2015 at 16:19:29 UTC, Jonathan M Davis wrote:Thank God, D does it the "not good" way. But I guess that is subjective thing. Some people like it one way, others like it the other way. I humbly belive D's way is good. Compiler should issue a warning when conflicts arrive. This is not Python for Haven's sake!You can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast.Check example again, you are only required to use the plain module name, not fully qualified one. With D syntax: import std.stdio; writeln(); // not good stdio.writeln(); // good std.stdio.writeln(); // also good, but not required
Aug 14 2015
On 08/14/2015 05:55 PM, Dejan Lekic wrote:On Thursday, 13 August 2015 at 16:22:04 UTC, Dicebot wrote:Rust supports both. D supports both. I still fail to see how one language can be seen to handle it in a "good" way and the other in a "not good" way, beyond trivial syntactic considerations and compiler bugs. Is it a language-cultural issue?On Thursday, 13 August 2015 at 16:19:29 UTC, Jonathan M Davis wrote:Thank God, D does it the "not good" way. But I guess that is subjective thing. Some people like it one way, others like it the other way. ...You can get that behavior with static imports in D, but having to use the whole import path while referencing symbols gets ugly fast.Check example again, you are only required to use the plain module name, not fully qualified one. With D syntax: import std.stdio; writeln(); // not good stdio.writeln(); // good std.stdio.writeln(); // also good, but not requiredI humbly belive D's way is good. Compiler should issue a warning when conflicts arrive.But only then, please. :o)
Aug 14 2015
On Thursday, 13 August 2015 at 15:29:19 UTC, Dicebot wrote:struct Something { public import a; } void main() { Something.foo(); }What's wrong with `import Something = a;`? Bugs?
Aug 13 2015
On Thursday, 13 August 2015 at 15:53:16 UTC, anonymous wrote:On Thursday, 13 August 2015 at 15:29:19 UTC, Dicebot wrote:Even better: feature.struct Something { public import a; } void main() { Something.foo(); }What's wrong with `import Something = a;`? Bugs?
Aug 13 2015
On Thursday, 13 August 2015 at 15:53:16 UTC, anonymous wrote:On Thursday, 13 August 2015 at 15:29:19 UTC, Dicebot wrote:Works only with a single import: import mypkg = mypkg.mysubpkg.mod1; import mypkg = mypkg.mysubpkg.mod2; // error, can't redefine aliased import! struct mypkg { import mypkg.mysubpkg.mod1; import mypkg.mysubpkg.mod2; // fine }struct Something { public import a; } void main() { Something.foo(); }What's wrong with `import Something = a;`? Bugs?
Aug 13 2015
As long as imports are not hygienic, this trick is useful. I
Aug 13 2015
On 8/13/2015 6:12 AM, Dicebot wrote:Right now this works: ``D struct Std { public import std.stdio; } void main() { Std.writeln("Nice!"); } ``` I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).It has nothing to do with aliases. Imports work the same way as template mixins do. They share the same implementation code. Since the import is qualified with 'public', I see no reason to change this behavior.
Aug 19 2015
On 08/20/2015 01:25 AM, Walter Bright wrote:This is exactly the right way to do it. Note that alias this doesn't get this right currently. It can be hijacked by local imports.I want to use it as an import hygiene idiom but not entirely sure if this behavior can be relied upon (or it is just a side effect of imports being implemented as aliases currently).It has nothing to do with aliases. Imports work the same way as template mixins do. They share the same implementation code.
Aug 19 2015