Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 00:35:50 UTC, Manu wrote: That's all you need really, any symbol you add will cause the error. extern(C++, bliz): created a symbol "bliz", you can't import a package from "bliz" cause then there's a symbol clash. I thought you implemented extern(C++) ... And yes, the example is actually complete. Again, but I'll simplify the filenames: ns/bar.d - module ns.bar; import ns.baz; extern(C++, ns): ns/baz.d - module ns.baz; import ns.bar; extern(C++, ns): dmd ns/bar.d ns/baz.d I just found this little hack for such situations. It seems like a combined effect of mixin template and normal mixin that seems to work by abusing the creation of temporary module for each instantiation. The obvious downside is mixin/CTFE being memory hungry and compilation times increase. Also not sure what happens when there is name clashes due to multiple symbols imported from multiple modules. Tested with DMD 2.082 -m32mscoff on Windows. file1.d ``` mixin template a01() { mixin(` extern(C++, namespaceone) public void fun (); `); } mixin a01; mixin template a02() { mixin(` extern(C++, namespaceone) public void otherfun (); `); } mixin a02; // the rest ``` file2.d ``` mixin template a03() { mixin(` extern(C++, namespaceone) public void yetanotherfun (); `); } mixin a03; // ... ```
Re: extern(C++, ns) is wrong
On Wed, 19 Sep 2018 at 13:15, Walter Bright via Digitalmars-d wrote: > > On 9/18/2018 5:22 PM, Manu wrote: > > Thank you Walter for coming to the party! > > I suppose I should explain this. > > 1. The PR uses a different syntax, i.e. strings instead of identifiers. This > implies it is not creating a scope, and doesn't interfere with the scoping of > the existing syntax. The design of the feature is simple and easy to document > and understand, and doesn't break anything. Wait up, just to be clear... is this a statement about the PR using strings different than your perception of the conversation surrounding this? This PR implements *exactly* what I was calling for literally the same day that the first patch introducing support was merged however many years ago, and every few months thereafter... I'm just curious to know if this PR was somehow surprising to you. Because if so, it demonstrates a total and colossal failure to communicate the preferred design of this feature ;) It was always desired to be a string from day -1, and the bugzilla issue presented it that way too.
Re: extern(C++, ns) is wrong
On 9/18/2018 5:22 PM, Manu wrote: Thank you Walter for coming to the party! I suppose I should explain this. 1. The PR uses a different syntax, i.e. strings instead of identifiers. This implies it is not creating a scope, and doesn't interfere with the scoping of the existing syntax. The design of the feature is simple and easy to document and understand, and doesn't break anything. 2. Manu and Atila are at the forefront of interfacing with C++. They are both doing massive amounts of work making it work. I'm willing to give a lot of deference to people who know what they are doing and have earned it through their major contributions and longtime membership in our community. 3. The PR for it looks to be a solid piece of work, and even if it turns out otherwise, it's pretty low risk and fixable. Thanks to Manu, Atila and look-at-me.
Re: extern(C++, ns) is wrong
On Wednesday, September 19, 2018 7:26:07 AM MDT Steven Schveighoffer via Digitalmars-d wrote: > On 9/18/18 9:49 PM, Jonathan M Davis wrote: > > On Tuesday, September 18, 2018 6:22:55 PM MDT Manu via Digitalmars-d wrote: > >> https://github.com/dlang/dmd/pull/8667 > >> > >> O_O > >> > >> Thank you Walter for coming to the party! > > > > Oh, wow. I sure wasn't expecting that. I thought that he'd made it > > pretty > > clear that a DIP was needed, and even then, it didn't seem likely that > > it > > would be accepted. This is awesome. I guess that he finally came around. > > I think a big part is that the implementation was done. I think there's > a big difference between "I don't really love this, but crap, I'll have > to implement it all" and "I don't really love this, but the > implementation isn't too intrusive, and all I have to do is click the > merge button, OK." I sure wish I had the skills to hack dmd, there are > so many ideas I'd like to see implemented in the language :) > > Anyways, great to see this merged! Having an implementation available hasn't always done the trick, but it's certainly easier to try to convince Walter accept something that's already been done than to convince him that he should implement something - which really shouldn't be a surprise. I expect that pretty much all of us are that way. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On 9/18/18 9:49 PM, Jonathan M Davis wrote: On Tuesday, September 18, 2018 6:22:55 PM MDT Manu via Digitalmars-d wrote: https://github.com/dlang/dmd/pull/8667 O_O Thank you Walter for coming to the party! Oh, wow. I sure wasn't expecting that. I thought that he'd made it pretty clear that a DIP was needed, and even then, it didn't seem likely that it would be accepted. This is awesome. I guess that he finally came around. I think a big part is that the implementation was done. I think there's a big difference between "I don't really love this, but crap, I'll have to implement it all" and "I don't really love this, but the implementation isn't too intrusive, and all I have to do is click the merge button, OK." I sure wish I had the skills to hack dmd, there are so many ideas I'd like to see implemented in the language :) Anyways, great to see this merged! -Steve
Re: extern(C++, ns) is wrong
On 19/09/2018 1:49 PM, Jonathan M Davis wrote: On Tuesday, September 18, 2018 6:22:55 PM MDT Manu via Digitalmars-d wrote: On Mon, 17 Sep 2018 at 06:00, Atila Neves via Digitalmars-d wrote: On Sunday, 16 September 2018 at 17:46:26 UTC, Steven Schveighoffer wrote: On 9/14/18 6:41 PM, Neia Neutuladh wrote: Specifically, Walter wants this to compile: module whatever; extern(C++, foo) void doStuff(); extern(C++, bar) void doStuff(); And he's not too concerned that you might have to use doubly fully qualified names to refer to C++ symbols, like: import core.stdcpp.sstream; import core.stdcpp.vector; core.stdcpp.vector.std.vector v; This is probably the best explanation of why the current situation sucks. -Steve Agreed. Up until now, I didn't even understand the rationale for why it works the way it does. https://github.com/dlang/dmd/pull/8667 O_O Thank you Walter for coming to the party! Oh, wow. I sure wasn't expecting that. I thought that he'd made it pretty clear that a DIP was needed, and even then, it didn't seem likely that it would be accepted. This is awesome. I guess that he finally came around. - Jonathan M Davis Indeed, thank you Walter!
Re: extern(C++, ns) is wrong
On Tuesday, September 18, 2018 6:22:55 PM MDT Manu via Digitalmars-d wrote: > On Mon, 17 Sep 2018 at 06:00, Atila Neves via Digitalmars-d > > wrote: > > On Sunday, 16 September 2018 at 17:46:26 UTC, Steven > > > > Schveighoffer wrote: > > > On 9/14/18 6:41 PM, Neia Neutuladh wrote: > > >> Specifically, Walter wants this to compile: > > >> > > >> module whatever; > > >> extern(C++, foo) void doStuff(); > > >> extern(C++, bar) void doStuff(); > > >> > > >> And he's not too concerned that you might have to use doubly > > >> fully qualified names to refer to C++ symbols, like: > > >> > > >> import core.stdcpp.sstream; > > >> import core.stdcpp.vector; > > >> core.stdcpp.vector.std.vector v; > > > > > > This is probably the best explanation of why the current > > > situation sucks. > > > > > > -Steve > > > > Agreed. Up until now, I didn't even understand the rationale for > > why it works the way it does. > > https://github.com/dlang/dmd/pull/8667 > > O_O > > Thank you Walter for coming to the party! Oh, wow. I sure wasn't expecting that. I thought that he'd made it pretty clear that a DIP was needed, and even then, it didn't seem likely that it would be accepted. This is awesome. I guess that he finally came around. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Mon, 17 Sep 2018 at 06:00, Atila Neves via Digitalmars-d wrote: > > On Sunday, 16 September 2018 at 17:46:26 UTC, Steven > Schveighoffer wrote: > > On 9/14/18 6:41 PM, Neia Neutuladh wrote: > > > >> Specifically, Walter wants this to compile: > >> > >> module whatever; > >> extern(C++, foo) void doStuff(); > >> extern(C++, bar) void doStuff(); > >> > >> And he's not too concerned that you might have to use doubly > >> fully qualified names to refer to C++ symbols, like: > >> > >> import core.stdcpp.sstream; > >> import core.stdcpp.vector; > >> core.stdcpp.vector.std.vector v; > > > > This is probably the best explanation of why the current > > situation sucks. > > > > -Steve > > Agreed. Up until now, I didn't even understand the rationale for > why it works the way it does. https://github.com/dlang/dmd/pull/8667 O_O Thank you Walter for coming to the party!
Re: extern(C++, ns) is wrong
On Sunday, 16 September 2018 at 17:46:26 UTC, Steven Schveighoffer wrote: On 9/14/18 6:41 PM, Neia Neutuladh wrote: Specifically, Walter wants this to compile: module whatever; extern(C++, foo) void doStuff(); extern(C++, bar) void doStuff(); And he's not too concerned that you might have to use doubly fully qualified names to refer to C++ symbols, like: import core.stdcpp.sstream; import core.stdcpp.vector; core.stdcpp.vector.std.vector v; This is probably the best explanation of why the current situation sucks. -Steve Agreed. Up until now, I didn't even understand the rationale for why it works the way it does.
Re: extern(C++, ns) is wrong
On 9/14/18 6:41 PM, Neia Neutuladh wrote: Specifically, Walter wants this to compile: module whatever; extern(C++, foo) void doStuff(); extern(C++, bar) void doStuff(); And he's not too concerned that you might have to use doubly fully qualified names to refer to C++ symbols, like: import core.stdcpp.sstream; import core.stdcpp.vector; core.stdcpp.vector.std.vector v; This is probably the best explanation of why the current situation sucks. -Steve
Re: extern(C++, ns) is wrong
On Saturday, 15 September 2018 at 00:07:44 UTC, Danni Coy wrote: So extern(C++,"ns") replaces the existing syntax It would be in addition, at least at first. The current syntax might be deprecated. and then improve D's general ability to hand functioning hijacking other functions would be the best solution D already has tools for this. and Walters modelling of namespaces is fixing the problem in the wrong place? The current solution solves the very uncommon problem of having two different namespaces in the same file, containing symbols with the same names (or, if functions, with common overloads), where the person writing the bindings needs to keep a one-to-one correspondence between C++ headers and D files, and they don't want to introduce any meaningless structs or templates. Specifically, Walter wants this to compile: module whatever; extern(C++, foo) void doStuff(); extern(C++, bar) void doStuff(); And he's not too concerned that you might have to use doubly fully qualified names to refer to C++ symbols, like: import core.stdcpp.sstream; import core.stdcpp.vector; core.stdcpp.vector.std.vector v;
Re: extern(C++, ns) is wrong
On Fri, Sep 14, 2018, 06:01 Jonathan M Davis via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Thursday, September 13, 2018 5:45:56 AM MDT Danni Coy via Digitalmars-d > wrote: > > On Thu, Sep 13, 2018 at 5:14 PM Jonathan M Davis via Digitalmars-d < > > > > digitalmars-d@puremagic.com> wrote: > > > The entire point of having extern(C++, "NS") would be to make it so > that > > > the > > > _only_ thing that it would affect would be the name mangling. > Everything > > > else is exactly the same behavior as it would be if you had the same > > > functions as extern(D). It would be up to the programmer to organize > > > them > > > exactly like it is with pure D code. If you think that putting two > > > functions > > > in the same module is too risky, then you can put them in separate > > > modules, but it certainly isn't going to be forced on you unless they > > > actually conflict. The fact that functions are extern(C++) would have > > > no impact on that whatsoever. > > > > Yeah I get all this. It just seems to me that the downsides of > > extern(C++,"ns") from Walter's point of view could be handled by the > > compiler at the cost of a bit of flexibility. > > I would like to know how difficult that would be to do and whether that > > would be more acceptable to Walter than what is being being proposed. > > I don't know what Walter would go for, but trying to do anything special > for > extern(C++, "NS") symbols pretty much defeats the whole purpose of using > extern(C++, "NS") over extern(C++, NS). And the issue that you are trying > to > find a way to prevent is something that D code in general has to worry > about, so I don't think that it makes any sense to try to treat extern(C++) > symbols as special to try to fix it. > > If we have extern(C++, "NS"), then anyone creating C++ bindings will have > to > worry about conflicts in exactly the same way that they would with D code. > You have to do that with extern(C++, NS) too. It's that it's then only with > the functions within that namespace. > > Walter's concerns seem to center around the idea that we somehow need to > model C++ namespaces in D, so that's really what needs to be addressed > somehow. The D module system gives us everything we need to lay out symbols > so that they don't conflict. The only thing that it can't do is allow you > to > put conflicting symbols in the same module, making it harder to have a > 1-to-1 correspondance between D modules and C++ header files in rare cases, > but all we need to do to solve that is to either leave in extern(C++, NS) > for those cases or to make it so that something like > > static NS1 > { > extern(C++, "NS1") static void foo(int bar); > } > > static NS2 > { > extern(C++, "NS2") static void foo(int bar); > } > > works (which is basically what extern(C++, NS) is doing anyway). But > honestly, in most cases, it just makes more sense to split up the symbols > between modules, and in the vast majority of cases, you simply don't have > multiple namespaces with conflicting symbols in the same header file. > > - Jonathan M Davis > So extern(C++,"ns") replaces the existing syntax and then improve D's general ability to hand functioning hijacking other functions would be the best solution and Walters modelling of namespaces is fixing the problem in the wrong place? >
Re: extern(C++, ns) is wrong
On Fri, Sep 14, 2018, 08:47 Manu via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Thu, 13 Sep 2018 at 04:46, Danni Coy via Digitalmars-d > wrote: > > > > On Thu, Sep 13, 2018 at 5:14 PM Jonathan M Davis via Digitalmars-d < > digitalmars-d@puremagic.com> wrote: > >> > >> The entire point of having extern(C++, "NS") would be to make it so > that the > >> _only_ thing that it would affect would be the name mangling. Everything > >> else is exactly the same behavior as it would be if you had the same > >> functions as extern(D). It would be up to the programmer to organize > them > >> exactly like it is with pure D code. If you think that putting two > functions > >> in the same module is too risky, then you can put them in separate > modules, > >> but it certainly isn't going to be forced on you unless they actually > >> conflict. The fact that functions are extern(C++) would have no impact > on > >> that whatsoever. > > > > Yeah I get all this. It just seems to me that the downsides of > extern(C++,"ns") from Walter's point of view could be handled by the > compiler at the cost of a bit of flexibility. > > What are the 'downsides' you refer to? And what 'flexibility' is lost? > The whole point is to gain flexibility. There's definitely no loss of > flexibility on the table here ;) > > > I would like to know how difficult that would be to do and whether that > would be more acceptable to Walter than what is being being proposed. > > You'll need to elaborate. What is being proposed is the simplest > possible, most plainly obvious, > let's-not-introduce-unwieldy-edge-cases solution. > > Walters named scope should be an unrelated and parallel feature if he > really wants it. > You are suggesting extern(c++,"ns") be a parallel feature to extern(c++,ns). I am asking how difficult technically would it be to have your syntax replace Walters but have the compiler check for the situations where a function from one C++ namespace might shadow one in a different namespace and emit either a warning or an error. Honestly I just want to know if going that path will have more or less friction from Walter. >
Re: extern(C++, ns) is wrong
On Friday, September 14, 2018 10:56:45 AM MDT Manu via Digitalmars-d wrote: > On Fri, 14 Sep 2018 at 07:55, 12345swordy via Digitalmars-d > > wrote: > > On Friday, 14 September 2018 at 13:10:07 UTC, Atila Neves wrote: > > > On Friday, 14 September 2018 at 09:56:52 UTC, Zot wrote: > > >> [...] > > > > > > I'm also completely in favour of what Manu is saying. The > > > current situation works for no one. I very much doubt that any > > > D programmer exists that wants what extern(C++) currently does. > > > > > > Yes, C++ namespaces are a mess. Who cares? We have modules. All > > > we want is to be able to link. > > > > > > Walter pointed out workarounds, but: they're solutions to a > > > problem that shouldn't exist; are ugly as sin; aren't even > > > sufficient for manually writing bindings in the way the author > > > intends. > > > > > > Forum chatter won't do it though, we need a DIP. > > > > Someone is already on it. > > https://github.com/look-at-me/DIPs/blob/please-for-the-love-of-all-thing > > s-good-and-holy-fix-cpp-mangling-please-ok-sorry/DIPs/DIPxCPP.md > I can't wait for a DIP. > That's like 12 months turnaround, and I've already lost weeks waiting > for some trivial PR's about version identifiers that are still > pending... this will take years. Per the current procedure, it pretty much has to be done via a DIP. It might be possible for it to be fast-tracked, but without Walter and/or Andrei being behind it from the get-go, the chances of that happening aren't good. Really, the only way that this could go quickly would be if Walter and/or Andrei were somehow convinced that extern(C++, NS) was completely broken and that it was critical that it be fixed ASAP. And clearly, Walter is going to be very hard to convince (though maybe we'll get lucky and Andrei will be easy to convince - I have no clue what his position on the issue is). The only real leverage here is likely that they think that C++ integration is important. However, as long as Walter thinks that what we have should work just fine, he's not about to rush to change it. Regardless, given Walter's position on the situation, we pretty much have to have a DIP if nothing else so that we have a clear, well-written document to present to him. Arguing about it in the newsgroup clearly isn't getting us anywhere. After a solid DIP is written, then _maybe_ we could find a way to expedite things, but I think that he's already made it pretty clear that if we want any chance of change, we need a DIP. And while the DIP process might be annoyingly slow, if we don't get a DIP in the queue, I think that it's pretty clear that nothing will change unless Walter or Andrei does something significant with extern(C++, NS) and gets really annoyed at how bad it is (which seems to be how Andrei usually gets fired up on fixing something that other people had been insisting needed to be changed, but he'd thought was fine). - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Fri, 14 Sep 2018 at 07:55, 12345swordy via Digitalmars-d wrote: > > On Friday, 14 September 2018 at 13:10:07 UTC, Atila Neves wrote: > > On Friday, 14 September 2018 at 09:56:52 UTC, Zot wrote: > >> [...] > > > > I'm also completely in favour of what Manu is saying. The > > current situation works for no one. I very much doubt that any > > D programmer exists that wants what extern(C++) currently does. > > > > Yes, C++ namespaces are a mess. Who cares? We have modules. All > > we want is to be able to link. > > > > Walter pointed out workarounds, but: they're solutions to a > > problem that shouldn't exist; are ugly as sin; aren't even > > sufficient for manually writing bindings in the way the author > > intends. > > > > Forum chatter won't do it though, we need a DIP. > Someone is already on it. > https://github.com/look-at-me/DIPs/blob/please-for-the-love-of-all-things-good-and-holy-fix-cpp-mangling-please-ok-sorry/DIPs/DIPxCPP.md I can't wait for a DIP. That's like 12 months turnaround, and I've already lost weeks waiting for some trivial PR's about version identifiers that are still pending... this will take years.
Re: extern(C++, ns) is wrong
On Friday, 14 September 2018 at 13:10:07 UTC, Atila Neves wrote: On Friday, 14 September 2018 at 09:56:52 UTC, Zot wrote: [...] I'm also completely in favour of what Manu is saying. The current situation works for no one. I very much doubt that any D programmer exists that wants what extern(C++) currently does. Yes, C++ namespaces are a mess. Who cares? We have modules. All we want is to be able to link. Walter pointed out workarounds, but: they're solutions to a problem that shouldn't exist; are ugly as sin; aren't even sufficient for manually writing bindings in the way the author intends. Forum chatter won't do it though, we need a DIP. Someone is already on it. https://github.com/look-at-me/DIPs/blob/please-for-the-love-of-all-things-good-and-holy-fix-cpp-mangling-please-ok-sorry/DIPs/DIPxCPP.md
Re: extern(C++, ns) is wrong
On Friday, 14 September 2018 at 09:56:52 UTC, Zot wrote: On Thursday, 13 September 2018 at 23:30:33 UTC, Jonathan M Davis wrote: On Thursday, September 13, 2018 4:43:47 PM MDT Manu via Digitalmars-d wrote: [...] I'm not disagreeing, but I'm not the person who needs to be convinced. Either way, a DIP needs to be produced which [...] As someone who does a lot of c/c++ binding I am 100% in favor of Manu's extern(C++, "ns") I also want to point out that extern should work in mixins (see bug https://issues.dlang.org/show_bug.cgi?id=12575). So probably a good idea to clearify interactions like that in a DIP as well. - Zot I'm also completely in favour of what Manu is saying. The current situation works for no one. I very much doubt that any D programmer exists that wants what extern(C++) currently does. Yes, C++ namespaces are a mess. Who cares? We have modules. All we want is to be able to link. Walter pointed out workarounds, but: they're solutions to a problem that shouldn't exist; are ugly as sin; aren't even sufficient for manually writing bindings in the way the author intends. Forum chatter won't do it though, we need a DIP.
Re: extern(C++, ns) is wrong
On Thursday, 13 September 2018 at 23:30:33 UTC, Jonathan M Davis wrote: On Thursday, September 13, 2018 4:43:47 PM MDT Manu via Digitalmars-d wrote: [...] I'm not disagreeing, but I'm not the person who needs to be convinced. Either way, a DIP needs to be produced which [...] As someone who does a lot of c/c++ binding I am 100% in favor of Manu's extern(C++, "ns") I also want to point out that extern should work in mixins (see bug https://issues.dlang.org/show_bug.cgi?id=12575). So probably a good idea to clearify interactions like that in a DIP as well. - Zot
Re: extern(C++, ns) is wrong
On Thursday, September 13, 2018 4:43:47 PM MDT Manu via Digitalmars-d wrote: > On Thu, 13 Sep 2018 at 13:01, Jonathan M Davis via Digitalmars-d > > wrote: > > Walter's concerns seem to center around the idea that we somehow need to > > model C++ namespaces in D, so that's really what needs to be addressed > > somehow. The D module system gives us everything we need to lay out > > symbols so that they don't conflict. The only thing that it can't do is > > allow you to put conflicting symbols in the same module, making it > > harder to have a 1-to-1 correspondance between D modules and C++ header > > files in rare cases, > But consider the overwhelmingly common case where C++ namespaces span > across many files. > You can't distribute extern(C++, ns) across D modules, so D fails to > model C++ namespaces regardless, and in the vast majority case. The > minority case you point out above is irrelevant by contrast. > The current design fails at its primary goal right out of the gate, > but we wear a pile of super-anger-inducing baggage in its wake. I'm not disagreeing, but I'm not the person who needs to be convinced. Either way, a DIP needs to be produced which 1. really clearly explains the semantics (which shouldn't be hard given their simplicity). 2. does an excellent job of explaining the downsides to the current approach, why they're such a big problem, why workarounds for those problems are terrible, and why the proposed approach doesn't have those same problems. 3. and of course, for thoroughness, it needs to explain the downsides to the proposed approach and the likely workarounds, but the issue of trying to put multiple namespaces in a single module when they were in a single header file is the only downside that I'm aware of. How easy it's going to be to put something together that convinces Walter, I don't know, but we clearly need a well-written DIP to stand a chance, and I have no clue what arguments would convince Walter. I don't know what Andrei thinks on the subject, but maybe the trick is to write the DIP so well that Andrei is convinced, and then _he_ convinces Walter. And maybe we'll get lucky, and after Walter mulls over it enough, he'll come around. I don't know. Either way, I don't think that you really need to convince many folks who have actually dealt with extern(C++, NS). At least out of those folks who say anything in the forums, it seems that pretty much anyone (other than Walter) who looks into the issue much pretty quickly comes to the conclusion that the current approach is terrible. It's Walter who is clearly hard to convince. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Thu, 13 Sep 2018 at 04:46, Danni Coy via Digitalmars-d wrote: > > On Thu, Sep 13, 2018 at 5:14 PM Jonathan M Davis via Digitalmars-d > wrote: >> >> The entire point of having extern(C++, "NS") would be to make it so that the >> _only_ thing that it would affect would be the name mangling. Everything >> else is exactly the same behavior as it would be if you had the same >> functions as extern(D). It would be up to the programmer to organize them >> exactly like it is with pure D code. If you think that putting two functions >> in the same module is too risky, then you can put them in separate modules, >> but it certainly isn't going to be forced on you unless they actually >> conflict. The fact that functions are extern(C++) would have no impact on >> that whatsoever. > > Yeah I get all this. It just seems to me that the downsides of > extern(C++,"ns") from Walter's point of view could be handled by the compiler > at the cost of a bit of flexibility. What are the 'downsides' you refer to? And what 'flexibility' is lost? The whole point is to gain flexibility. There's definitely no loss of flexibility on the table here ;) > I would like to know how difficult that would be to do and whether that would > be more acceptable to Walter than what is being being proposed. You'll need to elaborate. What is being proposed is the simplest possible, most plainly obvious, let's-not-introduce-unwieldy-edge-cases solution. Walters named scope should be an unrelated and parallel feature if he really wants it.
Re: extern(C++, ns) is wrong
On Thu, 13 Sep 2018 at 13:01, Jonathan M Davis via Digitalmars-d wrote: > > Walter's concerns seem to center around the idea that we somehow need to > model C++ namespaces in D, so that's really what needs to be addressed > somehow. The D module system gives us everything we need to lay out symbols > so that they don't conflict. The only thing that it can't do is allow you to > put conflicting symbols in the same module, making it harder to have a > 1-to-1 correspondance between D modules and C++ header files in rare cases, But consider the overwhelmingly common case where C++ namespaces span across many files. You can't distribute extern(C++, ns) across D modules, so D fails to model C++ namespaces regardless, and in the vast majority case. The minority case you point out above is irrelevant by contrast. The current design fails at its primary goal right out of the gate, but we wear a pile of super-anger-inducing baggage in its wake.
Re: extern(C++, ns) is wrong
On Thursday, September 13, 2018 5:45:56 AM MDT Danni Coy via Digitalmars-d wrote: > On Thu, Sep 13, 2018 at 5:14 PM Jonathan M Davis via Digitalmars-d < > > digitalmars-d@puremagic.com> wrote: > > The entire point of having extern(C++, "NS") would be to make it so that > > the > > _only_ thing that it would affect would be the name mangling. Everything > > else is exactly the same behavior as it would be if you had the same > > functions as extern(D). It would be up to the programmer to organize > > them > > exactly like it is with pure D code. If you think that putting two > > functions > > in the same module is too risky, then you can put them in separate > > modules, but it certainly isn't going to be forced on you unless they > > actually conflict. The fact that functions are extern(C++) would have > > no impact on that whatsoever. > > Yeah I get all this. It just seems to me that the downsides of > extern(C++,"ns") from Walter's point of view could be handled by the > compiler at the cost of a bit of flexibility. > I would like to know how difficult that would be to do and whether that > would be more acceptable to Walter than what is being being proposed. I don't know what Walter would go for, but trying to do anything special for extern(C++, "NS") symbols pretty much defeats the whole purpose of using extern(C++, "NS") over extern(C++, NS). And the issue that you are trying to find a way to prevent is something that D code in general has to worry about, so I don't think that it makes any sense to try to treat extern(C++) symbols as special to try to fix it. If we have extern(C++, "NS"), then anyone creating C++ bindings will have to worry about conflicts in exactly the same way that they would with D code. You have to do that with extern(C++, NS) too. It's that it's then only with the functions within that namespace. Walter's concerns seem to center around the idea that we somehow need to model C++ namespaces in D, so that's really what needs to be addressed somehow. The D module system gives us everything we need to lay out symbols so that they don't conflict. The only thing that it can't do is allow you to put conflicting symbols in the same module, making it harder to have a 1-to-1 correspondance between D modules and C++ header files in rare cases, but all we need to do to solve that is to either leave in extern(C++, NS) for those cases or to make it so that something like static NS1 { extern(C++, "NS1") static void foo(int bar); } static NS2 { extern(C++, "NS2") static void foo(int bar); } works (which is basically what extern(C++, NS) is doing anyway). But honestly, in most cases, it just makes more sense to split up the symbols between modules, and in the vast majority of cases, you simply don't have multiple namespaces with conflicting symbols in the same header file. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Thu, Sep 13, 2018 at 5:14 PM Jonathan M Davis via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > > > The entire point of having extern(C++, "NS") would be to make it so that > the > _only_ thing that it would affect would be the name mangling. Everything > else is exactly the same behavior as it would be if you had the same > functions as extern(D). It would be up to the programmer to organize them > exactly like it is with pure D code. If you think that putting two > functions > in the same module is too risky, then you can put them in separate modules, > but it certainly isn't going to be forced on you unless they actually > conflict. The fact that functions are extern(C++) would have no impact on > that whatsoever. > Yeah I get all this. It just seems to me that the downsides of extern(C++,"ns") from Walter's point of view could be handled by the compiler at the cost of a bit of flexibility. I would like to know how difficult that would be to do and whether that would be more acceptable to Walter than what is being being proposed.
Re: extern(C++, ns) is wrong
On Wednesday, September 12, 2018 11:29:42 PM MDT Danni Coy via Digitalmars-d wrote: > On Thu, Sep 13, 2018, 07:06 Manu via Digitalmars-d < > > digitalmars-d@puremagic.com> wrote: > > On Tue, 11 Sep 2018 at 20:59, Danni Coy via Digitalmars-d > > > > wrote: > > > So my understanding is that the main issue with extern(C++,"ns") is > > > > functions that have different C++ name-spaces overriding each other in > > unexpected ways. > > > > > How feasible is to simply disallow functions/variables/objects/... > > > with > > > > the same name but a different "ns" being in the same module? > > > > That's natural behaviour. You can't declare the same symbol twice in > > the same scope. > > Sorry I meant in the instance where a function has the same name but a > different signature and the wrong function might be called because of > implicit promotion of a variable. > > How feasible is it to have the compiler simply disallow this and force you > to put such functions in different d modules? The entire point of having extern(C++, "NS") would be to make it so that the _only_ thing that it would affect would be the name mangling. Everything else is exactly the same behavior as it would be if you had the same functions as extern(D). It would be up to the programmer to organize them exactly like it is with pure D code. If you think that putting two functions in the same module is too risky, then you can put them in separate modules, but it certainly isn't going to be forced on you unless they actually conflict. The fact that functions are extern(C++) would have no impact on that whatsoever. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Thu, Sep 13, 2018, 07:06 Manu via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Tue, 11 Sep 2018 at 20:59, Danni Coy via Digitalmars-d > wrote: > > > > > > > > So my understanding is that the main issue with extern(C++,"ns") is > functions that have different C++ name-spaces overriding each other in > unexpected ways. > > How feasible is to simply disallow functions/variables/objects/... with > the same name but a different "ns" being in the same module? > > That's natural behaviour. You can't declare the same symbol twice in > the same scope. > Sorry I meant in the instance where a function has the same name but a different signature and the wrong function might be called because of implicit promotion of a variable. How feasible is it to have the compiler simply disallow this and force you to put such functions in different d modules?
Re: extern(C++, ns) is wrong
On Wednesday, September 12, 2018 3:06:23 PM MDT Manu via Digitalmars-d wrote: > On Tue, 11 Sep 2018 at 20:59, Danni Coy via Digitalmars-d > > wrote: > > So my understanding is that the main issue with extern(C++,"ns") is > > functions that have different C++ name-spaces overriding each other in > > unexpected ways. How feasible is to simply disallow > > functions/variables/objects/... with the same name but a different "ns" > > being in the same module? > That's natural behaviour. You can't declare the same symbol twice in > the same scope. And that's really what's so nice about the idea behind extern(C++, "NS"). It's incredibly simple, because it follows _all_ of the normal D semantics. It's just that it then affects how the symbols are mangled so that they link up with the C++ symbols that they're bindings for. So, the whole thing is incredibly easy to reason about. The only downside that I'm aware of is that it makes it harder to put multiple namespaces in the same file, which matters if you're trying to put all of the symbols from a particular header file in a corresponding module. In every other respect, it's simpler - and incredibly easy to reason about. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Tue, 11 Sep 2018 at 20:59, Danni Coy via Digitalmars-d wrote: > > > > So my understanding is that the main issue with extern(C++,"ns") is functions > that have different C++ name-spaces overriding each other in unexpected ways. > How feasible is to simply disallow functions/variables/objects/... with the > same name but a different "ns" being in the same module? That's natural behaviour. You can't declare the same symbol twice in the same scope.
Re: extern(C++, ns) is wrong
On Tuesday, September 11, 2018 9:59:30 PM MDT Danni Coy via Digitalmars-d wrote: > So my understanding is that the main issue with extern(C++,"ns") is > functions that have different C++ name-spaces overriding each other in > unexpected ways. > How feasible is to simply disallow functions/variables/objects/... with > the same name but a different "ns" being in the same module? If we had extern(C++, "NS"), then all it would affect would be mangling and all of the normal rules for conflicting symbols would be in force. So, if you tried to put two symbols with the same name but from different namespaces in the same module, you'd get an error just like if they were D functions that conflicted. Disallowing it wouldn't be the problem. The problem would be if you were trying to match the C++ header file and thus have the two namespaces in the same file without a conflict, and that wouldn't work unless you could do something like put the symbol inside a struct or template to effectively namespace it - or if the current extern(C++, NS) mechanism were left in place in addition to adding extern(C++, "NS"). But for the most part, this is a non-issue, because the sane thing to do would be to just put different namespaces in different modules even if they were in the same header file in C++ - maybe pkg.headerfile.namespace instead of pkg.headerfile like you might do if everything in the header file were in the same namespace. It might be more of a problem with something that generated the bindings automatically, but mostly, the issue seems to be that Walter wants to be able to completely follow the C++ header scheme when you create the bindings, whereas most of the rest of us don't really care about being that exact about it if the header file did something like have multiple namespaces with symbols that would conflict if they were in the same namespace. Since the current scheme effectively creates namespaces inside of the module instead of just affecting the name mangling, you can stick as many namespaces in the module as you want without worrying about conflicts, but you then get other fun problems like having to declare everything in the namespace sequentially and having to refer everything in the namespace with the namespace unless you alias it all. So really, the most flexible solution would probably to have extern(C++, "NS") which only affects the mangling and then make sure that it works to do something like struct Namespace { extern(C++, "Namespace") static void foo(int bar); } thereby allowing you to have symbols from multiple namespaces in the same module even if they have conflicting names. In most cases, people would then just do extern(C++, "Namespace") void foo(int bar); and it's nice and simple, whereas if they really wanted to put conflicting symbols in the same module instead of just putting them in separate module like you would with D symbols, they could then explicitly namespace them. But given what we already have in the language, the simplest alternative would be to just add extern(C++, "Namespace") and leave extern(C++, Namespace) so that most code could use extern(C++, "Namespace"), and those rare cases where you really don't want to put conflicting symbols in separate modules, you use the current scheme of extern(C++, Namespace). The main downside is that having both constructs risks being confusing. Really though, there isn't much of a downside to the extern(C++, "Namespace") solution even if it were the only one. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Wednesday, 12 September 2018 at 03:59:30 UTC, Danni Coy wrote: So my understanding is that the main issue with extern(C++,"ns") is functions that have different C++ name-spaces overriding each other in unexpected ways. How feasible is to simply disallow functions/variables/objects/... with the same name but a different "ns" being in the same module? Very. The compiler would do it automatically because they would cause name collisions.
Re: extern(C++, ns) is wrong
So my understanding is that the main issue with extern(C++,"ns") is functions that have different C++ name-spaces overriding each other in unexpected ways. How feasible is to simply disallow functions/variables/objects/... with the same name but a different "ns" being in the same module?
Re: extern(C++, ns) is wrong
On Mon, 10 Sep 2018 at 13:40, Carl Sturtivant via Digitalmars-d wrote: > > On Wednesday, 5 September 2018 at 13:53:15 UTC, Jonathan M Davis > wrote: > > On Wednesday, September 5, 2018 7:03:26 AM MDT Nicholas Wilson > > via Digitalmars-d wrote: > >> [...] > > > > Based on everything Walter said in the previous thread, it > > honestly seems to me to be primarily like he just can't give up > > on the idea that D has to worry about modeling C++ namespaces. > > Pretty much all of the extra complications that come from the > > current approach stem from insisting on modeling namespaces in > > D instead of just treating the namespace as part of the > > information that you give to the compiler to indicate what the > > symbol in D is supposed to correspond to in C++ when the > > compiler goes to mangle it. > > > > [...] > > I wholeheartedly agree. C++ namespaces are a C++ language idea > that D has discarded in favor of much simpler facilities. > Injecting that back into D when linking to > C++ is polluting D with needless complexity at odds with that > gain in simplicity. The name collision problem with two > namespaces containing the same name can be resolved with much > simpler facilities. For example, at the point of the extern > declaration, the name of the linked entity could be provided as > an optional third parameter so that the name in D could be > different. I'm sure many other simple schemes could be invented, > more consistent with D's approach. This is a problem that doesn't need a solution. Just use modules; this is precisely what they're for. I, for one, have faith in the module design.
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 13:53:15 UTC, Jonathan M Davis wrote: On Wednesday, September 5, 2018 7:03:26 AM MDT Nicholas Wilson via Digitalmars-d wrote: [...] Based on everything Walter said in the previous thread, it honestly seems to me to be primarily like he just can't give up on the idea that D has to worry about modeling C++ namespaces. Pretty much all of the extra complications that come from the current approach stem from insisting on modeling namespaces in D instead of just treating the namespace as part of the information that you give to the compiler to indicate what the symbol in D is supposed to correspond to in C++ when the compiler goes to mangle it. [...] I wholeheartedly agree. C++ namespaces are a C++ language idea that D has discarded in favor of much simpler facilities. Injecting that back into D when linking to C++ is polluting D with needless complexity at odds with that gain in simplicity. The name collision problem with two namespaces containing the same name can be resolved with much simpler facilities. For example, at the point of the extern declaration, the name of the linked entity could be provided as an optional third parameter so that the name in D could be different. I'm sure many other simple schemes could be invented, more consistent with D's approach.
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 13:53:15 UTC, Jonathan M Davis wrote: Very well said, thanks. Based on everything Walter said in the previous thread, it honestly seems to me to be primarily like he just can't give up on the idea that D has to worry about modeling C++ namespaces. That is the conclusion I came to as well. What Walter did makes perfect sense if you assume that D needs to care about namespaces when using the C++ symbol in D, but the conclusion of the rest of us when looking at the problem has been that D really doesn't need to care about the namespaces beyond mangling, because D modules already solve the problem. I think this is the key insight, everything else follows from this. But regardless, I'm with you and Manu at this point in that I don't understand why extern(C++, "Namespace") isn't a clearly better (and simpler) solution overall. But maybe we'll get lucky and after Walter has thought about it long enough, he'll come around. Either way, per the current process, we would clearly need a DIP even if Walter already agreed. So, the next step is to write a DIP, and hopefully it can be written well enough that it's appropriately convincing unlike everything that has been argued thus far. Indeed, It is a pity the DIP pipeline is so full. Manu, what timeline do you ideally need this by? and do you have an implementation? Putting it into LDC is probably going to be the fastest given there are 3 high impact DIPs in the queue already + however long takes to get this trough and then implemented.
Re: extern(C++, ns) is wrong
On Wednesday, September 5, 2018 7:03:26 AM MDT Nicholas Wilson via Digitalmars-d wrote: > This is a prime example of an industry blocker if ever there was. > Yes there has been a lot of talking past each other, but surely > you understand _what_ Manu is wanting even if you seem to think > that your workarounds (which you called solutions) are > sufficient. It is backwards compatible and solves a clear need, I > don't see why this is such a contentious issue. Based on everything Walter said in the previous thread, it honestly seems to me to be primarily like he just can't give up on the idea that D has to worry about modeling C++ namespaces. Pretty much all of the extra complications that come from the current approach stem from insisting on modeling namespaces in D instead of just treating the namespace as part of the information that you give to the compiler to indicate what the symbol in D is supposed to correspond to in C++ when the compiler goes to mangle it. What Walter did makes perfect sense if you assume that D needs to care about namespaces when using the C++ symbol in D, but the conclusion of the rest of us when looking at the problem has been that D really doesn't need to care about the namespaces beyond mangling, because D modules already solve the problem. In actuality, there's no more need to worry about a C++ symbol's namespace when using it in D than there is to have to care about which header file a C symbol lives in when you use it in D. The module you put it in will likely relate to the header file that it comes from, and in the case of a C++ symbol, it may even relate to the namespace that it's in in C++, but that's just a matter of sanely organizing your bindings in D so that folks using the code will have an easy time finding the symbols if they know where they live in C/C++. It's not required for actually differentiating the symbols when using them in D. The modules already take care of that quite well. And if you really have a situation where multiple namespaces with the same symbol name live in a C++ header, and you want to put them in the same module in D, it should be trivial to stick them in structs, classes, or templates to namespace them like folks already sometimes do with D code when they want to emulate namespaces in D. Or if we left the current implementation in addition to what Manu wants, then the current approach could be used in those cases. So, the primary situation that Walter brought up with using the module system to differentiate symbols rather than having the compiler emulate the namespace like it currently does should be very solvable with what Manu wants, whereas every issue that Manu and Atila brought up required jumping through hoops in order to get it working with the current solution, and it frequently ends up not only being much harder to implement, but it's less user-friendly for the programmers using the bindings. So, if you can accept the idea that there really is no need to emulate C++ namespaces in D - even if you want to be able to stick multiple namespaces in the same module - then I really don't see any reason to prefer the current approach to extern(C++, "namespace") like Manu wants. But for whatever reason, Walter just doesn't seem to accept the idea that it's unnecessary to emulate namespaces in D in order to link to them, and he thinks that all of the hoops that it causes you to jump through are worse than the extra hoops that you would have to jump through to get multiple namespaces in the same file if extern(C++, namespace) weren't a thing. I can understand that from the standpoint that extern(C++, namespace) has already been implemented, whereas extern(C++, "namespace") has not been. So, even if we were to then have both instead of replacing one with the other, there's definitely work involved. However, I fail to understand why extern(C++, namespace) is superior from a technical perspective. Rather, it clearly has some serious drawbacks in comparison to extern(C++, "namespace"). But be it because of the effort involved with implementing a new solution, or because the current solution was his idea, or because of some other reason, thus far, Walter just doesn't seem to want to come around to the idea that all we need is the mangling, and then we should be able to do everything else we need with what D already provides. Worst case, we might need to make adjustments to make sure that something like static Namespace { extern(C++, "Namespace") static bool freeFunc(int foo); } can compile without expecting freeFunc to be part of a struct. But I'm pretty sure that even if that wouldn't work, a template could be used as the namespace isnead, and we could even choose to leave in extern(C++, Namespace) bool freeFunc(int foo); for the rare case where that makes more sense than simply letting the module system do its job. But regardless, I'm with you and Manu at this point in that I don't understand why extern(C++, "Namespace") isn't a
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 08:30:25 UTC, Walter Bright wrote: On 9/4/2018 10:16 PM, Manu wrote: I'm serious, you can have your cake, and potentially, I could have my cake too, and everybody would be happy... nobody would be sad. If it is the same, It is I provided solutions in those threads. The incomplete example code did not make use of them. Those "solutions" do not satisfactorily solve the problem, hence: I have to contort my code to undo a thing that should never have been there. It's truly >embarrassing. I can't show this to people. ***I can not present my work to stakeholders with a straight face*** I don't think I could either. I don't know why you have "no option" left. There is one: add it to LDC, which will accept it, see https://github.com/ldc-developers/ldc/issues/2800#issuecomment-410817126 but this is a language feature we (LDC) would rather not have an upstream diff for. This is a prime example of an industry blocker if ever there was. Yes there has been a lot of talking past each other, but surely you understand _what_ Manu is wanting even if you seem to think that your workarounds (which you called solutions) are sufficient. It is backwards compatible and solves a clear need, I don't see why this is such a contentious issue.
Re: extern(C++, ns) is wrong
On 05/09/2018 9:35 PM, Jonathan M Davis wrote: On Wednesday, September 5, 2018 2:30:25 AM MDT Walter Bright via Digitalmars-d wrote: On 9/4/2018 10:16 PM, Manu wrote: I'm serious, you can have your cake, and potentially, I could have my cake too, and everybody would be happy... nobody would be sad. If it is the same, I provided solutions in those threads. The incomplete example code did not make use of them. I don't know why you have "no option" left. If I understand correctly, what it basically comes down to is that Manu finds all of the workarounds that you've suggested to be so annoying as to be intolerable. And after running into some of the same problems yet again, he felt the need to complain about it again and beg you to change your mind, since he feels that he has no idea how to convince you. I get the impression that he thinks that his proposed solution is so obviously better that he doesn't understand why you don't see that it's better, but I don't know. Either way, I think that we all know that it can be very difficult to convince you of something (though that's true of many of us around here). :) From what I understand of the situation, I'm inclined to agree with Manu's position on this topic, but I thought that it was clear from the previous discussion that if there were any chance of anything changing, we were going to need a DIP. Based on everything that's been said thus far, I question that that stands much chance of convincing you, but I do think that we need a clear definition of the proposed solution so that we can avoid talking passed each other, which seemed to be happening at least some of the time in the recent thread. Either way, unless someone can come up with an example of the problem or argument about it that somehow convinces you when the previous examples and arguments didn't, I'm not sure that there's much point in arguing about it without at least having a clear DIP on the topic. - Jonathan M Davis +1 My interpretation is very similar, only difference is that Manu is asking for is removal of some artificial restrictions put in place to prevent possible problems that probably won't appear in D. I agree with the solution you have provided to move forward. I think we're done arguing, Walter just doesn't seem to want to accept Manu's use case as-is.
Re: extern(C++, ns) is wrong
On Wednesday, September 5, 2018 2:30:25 AM MDT Walter Bright via Digitalmars-d wrote: > On 9/4/2018 10:16 PM, Manu wrote: > > I'm serious, you can have your cake, and potentially, I could have my > > cake too, and everybody would be happy... nobody would be sad. > > If it is the same, I provided solutions in those threads. The incomplete > example code did not make use of them. > > I don't know why you have "no option" left. If I understand correctly, what it basically comes down to is that Manu finds all of the workarounds that you've suggested to be so annoying as to be intolerable. And after running into some of the same problems yet again, he felt the need to complain about it again and beg you to change your mind, since he feels that he has no idea how to convince you. I get the impression that he thinks that his proposed solution is so obviously better that he doesn't understand why you don't see that it's better, but I don't know. Either way, I think that we all know that it can be very difficult to convince you of something (though that's true of many of us around here). :) >From what I understand of the situation, I'm inclined to agree with Manu's position on this topic, but I thought that it was clear from the previous discussion that if there were any chance of anything changing, we were going to need a DIP. Based on everything that's been said thus far, I question that that stands much chance of convincing you, but I do think that we need a clear definition of the proposed solution so that we can avoid talking passed each other, which seemed to be happening at least some of the time in the recent thread. Either way, unless someone can come up with an example of the problem or argument about it that somehow convinces you when the previous examples and arguments didn't, I'm not sure that there's much point in arguing about it without at least having a clear DIP on the topic. - Jonathan M Davis
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 07:22:50 UTC, Paolo Invernizzi wrote: On Wednesday, 5 September 2018 at 05:32:43 UTC, Manu wrote: On Tue, 4 Sep 2018 at 21:40, Walter Bright via Digitalmars-d wrote: [...] "A handwavy description"! What do you mean? I started the email with the code... if you compiled it you would have reproduced those error messages. Yes the line numbers would have been different line numbers, because I deleted all the other lines, but the code I pasted reproduces the errors precisely. And you know that anyway. You don't need to compile the code to understand the error, we've been over it countless times for years now. what about run.dlang.org? I don't think you can link against C++ code there.
Re: extern(C++, ns) is wrong
On 9/4/2018 10:16 PM, Manu wrote: I'm serious, you can have your cake, and potentially, I could have my cake too, and everybody would be happy... nobody would be sad. If it is the same, I provided solutions in those threads. The incomplete example code did not make use of them. I don't know why you have "no option" left.
Re: extern(C++, ns) is wrong
On 9/4/2018 10:32 PM, Manu wrote: "A handwavy description"! What do you mean? I started the email with the code... if you compiled it you would have reproduced those error messages. There are 3 files referenced, but only two are given.
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 05:32:43 UTC, Manu wrote: On Tue, 4 Sep 2018 at 21:40, Walter Bright via Digitalmars-d wrote: [...] "A handwavy description"! What do you mean? I started the email with the code... if you compiled it you would have reproduced those error messages. Yes the line numbers would have been different line numbers, because I deleted all the other lines, but the code I pasted reproduces the errors precisely. And you know that anyway. You don't need to compile the code to understand the error, we've been over it countless times for years now. what about run.dlang.org?
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 21:40, Walter Bright via Digitalmars-d wrote: > > On 9/4/2018 5:31 PM, Manu wrote: > > I'm just showing one case that you tend to be confronted with > > immediately, which is that if you import a module, and then open a > > namespace with the same name as the root namespace of a module you > > imported, that is an error condition; the namespace conflicts with the > > root namespace of the import. > > I have 30 years of experience doing tech support. I'm not going to guess what > the problem is, or try to reconstruct an example from a handwavy description. > Been there, done that, far too many times. It just wastes my time and will > only > frustrate you because I'll solve a different problem. "A handwavy description"! What do you mean? I started the email with the code... if you compiled it you would have reproduced those error messages. Yes the line numbers would have been different line numbers, because I deleted all the other lines, but the code I pasted reproduces the errors precisely. And you know that anyway. You don't need to compile the code to understand the error, we've been over it countless times for years now.
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 22:05, Joakim via Digitalmars-d wrote: > > On Wednesday, 5 September 2018 at 01:20:26 UTC, Manu wrote: > > On Tue, 4 Sep 2018 at 17:50, tide via Digitalmars-d > > wrote: > >> > >> On Wednesday, 5 September 2018 at 00:35:50 UTC, Manu wrote: > >> > On Tue, 4 Sep 2018 at 17:30, tide via Digitalmars-d > >> > wrote: > >> >> [...] > >> > > >> > And yes, the example is actually complete. Again, but I'll > >> > simplify the filenames: > >> > > >> > ns/bar.d > >> > - > >> > module ns.bar; > >> > import ns.baz; > >> > extern(C++, ns): > >> > > >> > ns/baz.d > >> > - > >> > module ns.baz; > >> > import ns.bar; > >> > extern(C++, ns): > >> > > >> > > >> >> [...] > >> > >> Judging by the name of the modules are you working on an > >> Entity Component System for D :o ? > > > > Well, I'm clearly trying to call C++ code >_< > > I suggest you privately email Walter the exact code files you're > writing, with the exact reasons you think his workarounds are too > onerous. These piecemeal forum posts are going nowhere. Workaround: "Naming the binding the same name as the library is incompatible with binding to a library. You need to rename your binding to something other than the name of the library; perhaps you should append 'D', that sounds really pro." That's just not acceptable.
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 21:40, Walter Bright via Digitalmars-d wrote: > > On 9/4/2018 5:31 PM, Manu wrote: > > I'm just showing one case that you tend to be confronted with > > immediately, which is that if you import a module, and then open a > > namespace with the same name as the root namespace of a module you > > imported, that is an error condition; the namespace conflicts with the > > root namespace of the import. > > I have 30 years of experience doing tech support. I'm not going to guess what > the problem is, or try to reconstruct an example from a handwavy description. > Been there, done that, far too many times. It just wastes my time and will > only > frustrate you because I'll solve a different problem. A hand-wavy description? You recall that last uber-thread right? I can't add anything to that, and I'm not trying to... I'm just, literally, begging you to fix this. I'm serious, you can have your cake, and potentially, I could have my cake too, and everybody would be happy... nobody would be sad.
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 04:39:14 UTC, Walter Bright wrote: On 9/4/2018 5:31 PM, Manu wrote: I'm just showing one case that you tend to be confronted with immediately, which is that if you import a module, and then open a namespace with the same name as the root namespace of a module you imported, that is an error condition; the namespace conflicts with the root namespace of the import. I have 30 years of experience doing tech support. I'm not going to guess what the problem is, or try to reconstruct an example from a handwavy description. Been there, done that, far too many times. It just wastes my time and will only frustrate you because I'll solve a different problem. The problem has already been described clearly and doesn't really need to be shown.
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 01:20:26 UTC, Manu wrote: On Tue, 4 Sep 2018 at 17:50, tide via Digitalmars-d wrote: On Wednesday, 5 September 2018 at 00:35:50 UTC, Manu wrote: > On Tue, 4 Sep 2018 at 17:30, tide via Digitalmars-d > wrote: >> [...] > > And yes, the example is actually complete. Again, but I'll > simplify the filenames: > > ns/bar.d > - > module ns.bar; > import ns.baz; > extern(C++, ns): > > ns/baz.d > - > module ns.baz; > import ns.bar; > extern(C++, ns): > > >> [...] Judging by the name of the modules are you working on an Entity Component System for D :o ? Well, I'm clearly trying to call C++ code >_< I suggest you privately email Walter the exact code files you're writing, with the exact reasons you think his workarounds are too onerous. These piecemeal forum posts are going nowhere.
Re: extern(C++, ns) is wrong
On 9/4/2018 5:31 PM, Manu wrote: I'm just showing one case that you tend to be confronted with immediately, which is that if you import a module, and then open a namespace with the same name as the root namespace of a module you imported, that is an error condition; the namespace conflicts with the root namespace of the import. I have 30 years of experience doing tech support. I'm not going to guess what the problem is, or try to reconstruct an example from a handwavy description. Been there, done that, far too many times. It just wastes my time and will only frustrate you because I'll solve a different problem.
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 17:50, tide via Digitalmars-d wrote: > > On Wednesday, 5 September 2018 at 00:35:50 UTC, Manu wrote: > > On Tue, 4 Sep 2018 at 17:30, tide via Digitalmars-d > > wrote: > >> > >> On Tuesday, 4 September 2018 at 23:32:31 UTC, Walter Bright > >> wrote: > >> > On 9/4/2018 3:33 PM, Manu wrote: > >> >> file1.d > >> >> - > >> >> module bliz.ecs.component_access; > >> >> import bliz.ecs.table; > >> >> import bliz.ecs.types; > >> >> extern(C++, bliz): > >> >> // things... > >> >> > >> >> Error: > >> >> project\ecs\include\d2\bliz\ecs\component_access.d(7): > >> >> Error: > >> >> namespace `bliz.ecs.component_access.bliz` conflicts with > >> >> import > >> >> `bliz.ecs.component_access.bliz` at > >> >> project\ecs\include\d2\bliz\ecs\component_access.d(3) > >> >> > >> >> file2.d > >> >> - > >> >> module bliz.ecs.table; > >> >> import bliz.ecs.types; > >> >> extern(C++, bliz): > >> >> // things... > >> >> > >> >> Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: > >> >> namespace > >> >> `bliz.ecs.table.bliz` conflicts with import > >> >> `bliz.ecs.table.bliz` at > >> >> project\ecs\include\d2\bliz\ecs\table.d(5) > >> > > >> > I can't help because the examples are incomplete. There is > >> > no line 5 in table.d, nor a line 7 in component_access.d The > >> > error messages are not generated from the code posted. > >> > >> That's all you need really, any symbol you add will cause the > >> error. > >> > >> extern(C++, bliz): > >> > >> created a symbol "bliz", you can't import a package from > >> "bliz" cause then there's a symbol clash. I thought you > >> implemented extern(C++) ... > > > > And yes, the example is actually complete. Again, but I'll > > simplify the filenames: > > > > ns/bar.d > > - > > module ns.bar; > > import ns.baz; > > extern(C++, ns): > > > > ns/baz.d > > - > > module ns.baz; > > import ns.bar; > > extern(C++, ns): > > > > > >> dmd ns/bar.d ns/baz.d > > Judging by the name of the modules are you working on an Entity > Component System for D :o ? Well, I'm clearly trying to call C++ code >_<
Re: extern(C++, ns) is wrong
On Wednesday, 5 September 2018 at 00:35:50 UTC, Manu wrote: On Tue, 4 Sep 2018 at 17:30, tide via Digitalmars-d wrote: On Tuesday, 4 September 2018 at 23:32:31 UTC, Walter Bright wrote: > On 9/4/2018 3:33 PM, Manu wrote: >> file1.d >> - >> module bliz.ecs.component_access; >> import bliz.ecs.table; >> import bliz.ecs.types; >> extern(C++, bliz): >> // things... >> >> Error: >> project\ecs\include\d2\bliz\ecs\component_access.d(7): >> Error: >> namespace `bliz.ecs.component_access.bliz` conflicts with >> import >> `bliz.ecs.component_access.bliz` at >> project\ecs\include\d2\bliz\ecs\component_access.d(3) >> >> file2.d >> - >> module bliz.ecs.table; >> import bliz.ecs.types; >> extern(C++, bliz): >> // things... >> >> Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: >> namespace >> `bliz.ecs.table.bliz` conflicts with import >> `bliz.ecs.table.bliz` at >> project\ecs\include\d2\bliz\ecs\table.d(5) > > I can't help because the examples are incomplete. There is > no line 5 in table.d, nor a line 7 in component_access.d The > error messages are not generated from the code posted. That's all you need really, any symbol you add will cause the error. extern(C++, bliz): created a symbol "bliz", you can't import a package from "bliz" cause then there's a symbol clash. I thought you implemented extern(C++) ... And yes, the example is actually complete. Again, but I'll simplify the filenames: ns/bar.d - module ns.bar; import ns.baz; extern(C++, ns): ns/baz.d - module ns.baz; import ns.bar; extern(C++, ns): dmd ns/bar.d ns/baz.d Judging by the name of the modules are you working on an Entity Component System for D :o ?
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 17:30, tide via Digitalmars-d wrote: > > On Tuesday, 4 September 2018 at 23:32:31 UTC, Walter Bright wrote: > > On 9/4/2018 3:33 PM, Manu wrote: > >> file1.d > >> - > >> module bliz.ecs.component_access; > >> import bliz.ecs.table; > >> import bliz.ecs.types; > >> extern(C++, bliz): > >> // things... > >> > >> Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): > >> Error: > >> namespace `bliz.ecs.component_access.bliz` conflicts with > >> import > >> `bliz.ecs.component_access.bliz` at > >> project\ecs\include\d2\bliz\ecs\component_access.d(3) > >> > >> file2.d > >> - > >> module bliz.ecs.table; > >> import bliz.ecs.types; > >> extern(C++, bliz): > >> // things... > >> > >> Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: > >> namespace > >> `bliz.ecs.table.bliz` conflicts with import > >> `bliz.ecs.table.bliz` at > >> project\ecs\include\d2\bliz\ecs\table.d(5) > > > > I can't help because the examples are incomplete. There is no > > line 5 in table.d, nor a line 7 in component_access.d The error > > messages are not generated from the code posted. > > That's all you need really, any symbol you add will cause the > error. > > extern(C++, bliz): > > created a symbol "bliz", you can't import a package from "bliz" > cause then there's a symbol clash. I thought you implemented > extern(C++) ... And yes, the example is actually complete. Again, but I'll simplify the filenames: ns/bar.d - module ns.bar; import ns.baz; extern(C++, ns): ns/baz.d - module ns.baz; import ns.bar; extern(C++, ns): > dmd ns/bar.d ns/baz.d
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 16:35, Walter Bright via Digitalmars-d wrote: > > On 9/4/2018 3:33 PM, Manu wrote: > > file1.d > > - > > module bliz.ecs.component_access; > > import bliz.ecs.table; > > import bliz.ecs.types; > > extern(C++, bliz): > > // things... > > > > Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): Error: > > namespace `bliz.ecs.component_access.bliz` conflicts with import > > `bliz.ecs.component_access.bliz` at > > project\ecs\include\d2\bliz\ecs\component_access.d(3) > > > > file2.d > > - > > module bliz.ecs.table; > > import bliz.ecs.types; > > extern(C++, bliz): > > // things... > > > > Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: namespace > > `bliz.ecs.table.bliz` conflicts with import `bliz.ecs.table.bliz` at > > project\ecs\include\d2\bliz\ecs\table.d(5) > > I can't help because the examples are incomplete. There is no line 5 in > table.d, > nor a line 7 in component_access.d The error messages are not generated from > the > code posted. I'm not asking for help. I know painfully well all the workarounds required to make this stuff work. I'm just showing one case that you tend to be confronted with immediately, which is that if you import a module, and then open a namespace with the same name as the root namespace of a module you imported, that is an error condition; the namespace conflicts with the root namespace of the import.
Re: extern(C++, ns) is wrong
On Tuesday, 4 September 2018 at 23:32:31 UTC, Walter Bright wrote: On 9/4/2018 3:33 PM, Manu wrote: file1.d - module bliz.ecs.component_access; import bliz.ecs.table; import bliz.ecs.types; extern(C++, bliz): // things... Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): Error: namespace `bliz.ecs.component_access.bliz` conflicts with import `bliz.ecs.component_access.bliz` at project\ecs\include\d2\bliz\ecs\component_access.d(3) file2.d - module bliz.ecs.table; import bliz.ecs.types; extern(C++, bliz): // things... Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: namespace `bliz.ecs.table.bliz` conflicts with import `bliz.ecs.table.bliz` at project\ecs\include\d2\bliz\ecs\table.d(5) I can't help because the examples are incomplete. There is no line 5 in table.d, nor a line 7 in component_access.d The error messages are not generated from the code posted. That's all you need really, any symbol you add will cause the error. extern(C++, bliz): created a symbol "bliz", you can't import a package from "bliz" cause then there's a symbol clash. I thought you implemented extern(C++) ...
Re: extern(C++, ns) is wrong
On 9/4/2018 3:33 PM, Manu wrote: file1.d - module bliz.ecs.component_access; import bliz.ecs.table; import bliz.ecs.types; extern(C++, bliz): // things... Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): Error: namespace `bliz.ecs.component_access.bliz` conflicts with import `bliz.ecs.component_access.bliz` at project\ecs\include\d2\bliz\ecs\component_access.d(3) file2.d - module bliz.ecs.table; import bliz.ecs.types; extern(C++, bliz): // things... Error: project\ecs\include\d2\bliz\ecs\table.d(11): Error: namespace `bliz.ecs.table.bliz` conflicts with import `bliz.ecs.table.bliz` at project\ecs\include\d2\bliz\ecs\table.d(5) I can't help because the examples are incomplete. There is no line 5 in table.d, nor a line 7 in component_access.d The error messages are not generated from the code posted.
Re: extern(C++, ns) is wrong
On Tue, 4 Sep 2018 at 16:00, Neia Neutuladh via Digitalmars-d wrote: > > On Tuesday, 4 September 2018 at 22:33:34 UTC, Manu wrote: > > Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): > > Error: namespace `bliz.ecs.component_access.bliz` conflicts > > with import `bliz.ecs.component_access.bliz` at > > project\ecs\include\d2\bliz\ecs\component_access.d(3) > > The obvious workaround is to wrap the entire C++ library in one > file, right? Nothing could possibly be suboptimal about that. > Just shove four thousand class definitions in there, it'll be > fine. Even that still wouldn't solve this problem where the root namespace can't be the same as the C++ namespace... which is the common-sense choice for the root namespace >_< I need to think up pointlessly different names for all the C++ package names to call the packages in D.
Re: extern(C++, ns) is wrong
On Tuesday, 4 September 2018 at 22:33:34 UTC, Manu wrote: Error: project\ecs\include\d2\bliz\ecs\component_access.d(7): Error: namespace `bliz.ecs.component_access.bliz` conflicts with import `bliz.ecs.component_access.bliz` at project\ecs\include\d2\bliz\ecs\component_access.d(3) The obvious workaround is to wrap the entire C++ library in one file, right? Nothing could possibly be suboptimal about that. Just shove four thousand class definitions in there, it'll be fine.
Re: extern(C++, ns)
On Thursday, 7 January 2016 at 18:17:24 UTC, Walter Bright wrote: On 1/7/2016 9:02 AM, Carl Sturtivant wrote: I should have noticed this too; so in fact the current design can be used ignoring the scope modeling the C++ namespace. If the details of using such an external name in that fashion are identical to any other name at module scope in every context, then I therefore concede that the design is OK, because it may be treated as the alternative suggested in various ways in this thread by simply ignoring the new scope by not using its name. The idea is most definitely that it follows the usual D scoping and name lookup rules. Note that 'alias' works much like symbolic links do in the Linux filesystem, in that it can make names appear in multiple scopes without needing qualification. So what do you make of Manu's last post? http://forum.dlang.org/post/mailman.3421.1452230079.22025.digitalmar...@puremagic.com Specifically, he gives examples of name collisions and scope problems that apparently could be avoided simply only if there is no named scope modeling a C++ namespace.
Re: extern(C++, ns)
On Saturday, 30 January 2016 at 21:06:22 UTC, Carl Sturtivant wrote: So what do you make of Manu's last post? http://forum.dlang.org/post/mailman.3421.1452230079.22025.digitalmar...@puremagic.com Specifically, he gives examples of name collisions and scope problems that apparently could be avoided simply only if there is no named scope modeling a C++ namespace. Apologies, I somehow posted while unaware of all the intervening discussion.
Re: extern(C++, ns)
On Friday, 22 January 2016 at 17:04:00 UTC, Jacob Carlborg wrote: Unfortunately that's not how it works with D. If Andrei or Walter have a proposal it's up to the community to provide compelling evidence why it _should not_ be added. If the community has a proposal it's up to the community to provide compelling evidence why is _should_ be added. Just to make sure there are no misunderstandings: This is not at all the point I was trying to make. My arguments apply just as well to just a single person deliberating the design: Adding a new feature requires justification, especially if the language is quite large already. Not adding one does not to the same extent, because it is the natural, less risky choice. — David
Re: extern(C++, ns)
On Thursday, 21 January 2016 at 00:43:13 UTC, David Nadlinger wrote: If you want to split up the interface to a C++ namespace among different modules, then the different symbols will *always* reside in different fully qualified scopes – with or without additional scopes being introduced by extern(C++)! This is the nub of the problem, and it's been stated by several people in several different ways in this thread. It means that a C++ namespace which is a single scope, is mapped into one scope per module in D. The C++ namespace scope has been fragmented to make it consistent with D's module philosophy. The result is natural neither for C++ nor for D.
Re: extern(C++, ns)
On Sunday, 31 January 2016 at 01:12:11 UTC, Carl Sturtivant wrote: This is the nub of the problem, and it's been stated by several people in several different ways in this thread. It means that a C++ namespace which is a single scope, is mapped into one scope per module in D. The C++ namespace scope has been fragmented to make it consistent with D's module philosophy. The result is natural neither for C++ nor for D. In fact, if you're going to bring in a scope to represent a namespace, that's what it needs to be a (singular) scope. Not to bring in many identical but distinct scopes. The present design is falling between two stools. They are to do the above or to just link mangled according to the namespace with no scope special C++ derived scope(s).
Re: extern(C++, ns)
D generally doesn't allow shadowing of names inside inner scopes. int x; for (int i=0; iwrote: > On 2016-01-21 00:50, David Nadlinger wrote: > >> To add a new feature to the language, the >> onus is on you to provide compelling evidence why it is necessary to >> have. You need to show that there is a "serious problem" with just using >> the native D namespacing scheme (modules) for the purpose, not the other >> way round. > > > Unfortunately that's not how it works with D. If Andrei or Walter have a > proposal it's up to the community to provide compelling evidence why it > _should not_ be added. If the community has a proposal it's up to the > community to provide compelling evidence why is _should_ be added. > > -- > /Jacob Carlborg
Re: extern(C++, ns)
On 2016-01-21 00:50, David Nadlinger wrote: To add a new feature to the language, the onus is on you to provide compelling evidence why it is necessary to have. You need to show that there is a "serious problem" with just using the native D namespacing scheme (modules) for the purpose, not the other way round. Unfortunately that's not how it works with D. If Andrei or Walter have a proposal it's up to the community to provide compelling evidence why it _should not_ be added. If the community has a proposal it's up to the community to provide compelling evidence why is _should_ be added. -- /Jacob Carlborg
Re: extern(C++, ns)
On Thursday, 21 January 2016 at 00:51:34 UTC, Anon wrote: What would you all say to the following proposal (and should I make a DIP?) 1. deprecate pragma(mangle) 2. deprecate extern(C++, ns) 3. deprecate @selector() 4. Introduce a better, more general extern() as follows: extern ( [, ] ) ... I was going to propose an additional syntax `extern(C++, "string")` (that doesn't introduce a scope) as a compromise, but your suggestion to extend it to all kinds of foreign languages is even better. I haven't read your proposal in detail, but I definitely like the general idea.
Re: extern(C++, ns)
On 21/01/2016 9:15 AM, Walter Bright wrote: On 1/20/2016 8:38 AM, Marc Schütz wrote: IMO his description was already quite clear, but here you are: What's missing is why this is a *serious* problem. All you've got to do is add a qualifier. The *serious* problem is that the added scope does not appear to add practical value, yet has a non-zero cost. And yes I've seen your example with two same-named symbols in the same module, but I really don't understand why *that* is a serious problem that the namespace scope is worth introducing to solve. And I am not personally arguing for D modules mapping to C++ namespaces - the alternative feature I have in mind is extern(C++, "namespace") affecting mangling and *nothing else*.
Re: extern(C++, ns)
On 1/20/2016 3:53 PM, tsbockman wrote: The thought of needing to do that for (potentially) every single symbol being imported is depressing. What happened to DRY? Since it is completely mechanical, it's an ideal candidate for writing a metafunction to do it: module stl-- private import core.stdcpp.vector; private import core.stdcpp.string; ... extern (C++, std) { mixin(aliasAllNamespaceMembers()); }
Re: extern(C++, ns)
I'm not sure what situation you're imagining where modules would be created with the same names...? How do you plan to map C++'s standard lib ? One giant hundred of thousands of line C++ file ? Surely it would map by file. #include -> import stl.vector; #include -> import stl.map; #include -> import stl.string; Perhaps 'stl' may be something else, 'std' is an unfortunate conflict with phobos, but this is unique to this case. But, in this case, I can't have an stl.vector!X which would map to an std::vector . The namespacing of symbol has been completely changed. I'd suggest it's the only possible way to make it feel the same. It's a no-brainer for the binding author, copy and rename .h files to .d, then regex until finished. That would require to have a similar namespacing, unless extern(C++, name) introduce a symbol called name. Note that the conflict rule can be tuned the same way it is specified for multiple alias this and you get something really nice. What case is there where a C++ lib distributing its symbols naturally among modules named accordingly with the original include's would cause confusion when compared against the C++ docs? Doc says '#include ', I'll 'import libname.feature;' Nothing could be more natural than this. As a bonus, the project's C++ namespace 'libname' is already present in the fully qualified name, it's the top level package! No point repeating that as 'libname.feature.libname.symbol'. I think it does make sense to make the C++ namespace "skippable", alias this style, while keeping it around to disambiguate. It is clear that C++ having namespacing and header being decoupled will cause problem if namespaces do not introduce a symbol.
Re: extern(C++, ns)
On 1/20/2016 4:51 PM, Anon wrote: What would you all say to the following proposal (and should I make a DIP?) DIPs are always welcome.
Re: extern(C++, ns)
On Thursday, 21 January 2016 at 01:37:12 UTC, Walter Bright wrote: On 1/20/2016 4:51 PM, Anon wrote: What would you all say to the following proposal (and should I make a DIP?) DIPs are always welcome. Done. http://forum.dlang.org/post/ldtluvnhuznvbebcb...@forum.dlang.org
Re: extern(C++, ns)
What would you all say to the following proposal (and should I make a DIP?) 1. deprecate pragma(mangle) 2. deprecate extern(C++, ns) 3. deprecate @selector() 4. Introduce a better, more general extern() as follows: extern ( [, ] ) Which would *only* influence mangling and calling conventions. Blocks would concatenate their s, with the default value for a symbol being its identifier. Whatever the concatenated string is then gets run through a language-specific mangler with knowledge of the type info. It would be an error for nesting blocks to change language. The content of the string would depend on the language in question. This would be also extendable beyond C, C++, D, and Objective-C to other languages if so desired (Rust, Go, C#, etc.) while keeping a uniform syntax and behavior regardless of the language being bound. Some examples: extern(C) int foo(); // Mangled as "foo" extern(C, "body") int body_(); // "body" extern(C++) int foo(); // cppMangleOf("foo") extern(C++, "body") int body_(); // cppMangleOf("body") extern(D) int foo(); // "_D3fooFZi" -no module extern(D, "body") int body_; // "_D4bodyFZi" -no module extern(C++, "ns::foo") int foo(); // cppMangleOf("ns::foo") extern(C++, "ns::") { int foo(); // cppMangleOf("ns::foo") extern(C++, "body") int body_(); // cppMangleOf("ns::body") // I'm unsure of the next two. Both need to be inside an // extern() block and would infer the // extern("with") int with_(); // cppMangleOf("ns::with") // extern(auto, "with") int with_(); // cppMangleOf("ns::with") } extern(C, "SDL_") { void init(); // "SDL_init" } extern(D, "std.ascii.") { // std.ascii.isAlphaNum.mangleof bool isAlphaNum(dchar) pure nothrow @nogc @safe bool; }
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 23:21:49 UTC, Walter Bright wrote: On 1/20/2016 3:12 PM, Martin Drašar via Digitalmars-d wrote: The "serious" problem is that the decision to have a namespace introduce a new scope needlessly complicates writing D-like interfaces to C++ code, while catering for one specific use-case that is considered niche. Adding a qualifier here and there does not count as serious. But, to put this statement in the context of my other post, it further raises the bar which the arguments in favor of having extern(C++) introduce D-side scopes have to clear. If we had extern(C++, "ns") just affect the mangling, the need for adding extra qualifiers wouldn't exist in the first place. — David
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 12:47:44 UTC, Manu wrote: 2. Multiple modules cannot have the same name in D. I'm not sure what situation you're imagining where modules would be created with the same names...? How do you plan to map C++'s standard lib ? One giant hundred of thousands of line C++ file ? Surely it would map by file. #include -> import stl.vector; #include -> import stl.map; #include -> import stl.string; Perhaps 'stl' may be something else, 'std' is an unfortunate conflict with phobos, but this is unique to this case. I believe deadalnix here meant something like this: import stl.vector; import mylib.vector; Vector a; // Ambiguous: could be from mylib or stl stl.Vector b; // Error: no such class stl.Vector stl.vector.Vector c; // Works, but requires extra typing Which with working namespaces might allow case b to work. -- Simen
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 17:25:56 UTC, JohnCK wrote: On Wednesday, 20 January 2016 at 16:38:19 UTC, Marc Schütz wrote: I think the first error is correct: bar(); // Error: b.bar at b.d(6) conflicts with a.ns.bar at a.d(5) Yes, I put this one in to show why the next lines are sometimes necessary. So you have two functions bar() one inside 'ns' in module a and "outside" 'ns' in module b. Now, the last 2 errors, Mark Schutz said: a.ns.bar(); // works, but requires superfluous `a`, even though // `ns` already makes it unambiguous Question: What happens if you do this: using "ns1" in "module a" and "ns2" in "module b" and do: ns1.bar(); ? There'd be no collision anymore, but... Because you can't have more than one namespaces with the same name in C++, right? You can: namespace ns { void foo(); } namespace ns { void bar(); } int main() { ns::bar(); return 0; } More realistically, the namespace declarations would appear in different header files, all #included into the same cpp file. These different header files would naturally be mapped to different D modules.
Re: extern(C++, ns)
On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: -- name.x.d module name.x; -- name.y.d module name.y; import name.x; extern(C++, name) int x; This won't work any more than: import name.y; struct name { } would. You can't have two different definitions for the same identifier in the same scope, and that's true for any programming language I've heard of. extern(C++, delegate) int x; Yes, we've talked about that. I'm thinking of a solution where it could be written like: extern(C++, delegate_) int x; and the C++ name mangler strips off any trailing _. Note that this problem is NOT resolved by your proposed solution, as this wouldn't work, either: extern(C++) int* delegate(); or any other use of D keywords as C/C++ identifiers. https://issues.dlang.org/show_bug.cgi?id=15587 You claim this is a problem that must desperately be solved: int x; extern(C++, ns) int x; The solution arrives at basically the same problem: int ns; extern(C++, ns) int x; We've just robbed peter to pay paul? C++ doesn't allow: int ns; namespace ns { ... } either, so there can never be a need to solve that problem. scanning reflection needs to be retrofit with new tricks to recurse into namespaces: extern(C++, ns) void f(); pragma(msg, __traits(allMembers, mixin(__MODULE__))); tuple("object", "ns") ... f() is not present. By extension of this, extern(C++, ns) declarations are incompatible with every single implementation of scanning reflection I've written in the past 6 years, and everyone else's too. All such code needs to be retrofit with new tricks to recurse into ns. Seems to me that all that is necessary is to replace: __traits(allMembers, mixin(__MODULE__)) with: getAllMembersIncludingNs(mixin(__MODULE__)) and then write getAllMembersIncludingNS() as a function that recursively adds members of namespaces. After all, the ugly __traits() was always meant to be a building block to be encapsulated by a function that does what is really wanted. I wouldn't call it tricky.
Re: extern(C++, ns)
On 01/20/2016 09:56 PM, Walter Bright wrote: On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: -- name.x.d module name.x; -- name.y.d module name.y; import name.x; extern(C++, name) int x; This won't work ... The suggestion was to just not introduce a new symbol/scope for the namespace. It would certainly work.
Re: extern(C++, ns)
On 1/20/2016 4:47 AM, Manu via Digitalmars-d wrote: As a bonus, the project's C++ namespace 'libname' is already present in the fully qualified name, it's the top level package! No point repeating that as 'libname.feature.libname.symbol'. You can always write a module that all it does is import a bunch of other modules, with a bunch of aliases which can be used to make those imports appear in another namespace: module core.stdcpp.vector extern (C++, std) { struct vector { } } module core.stdcpp.string extern (C++, std) { struct string { } } module stl-- private import core.stdcpp.vector; private import core.stdcpp.string; ... extern (C++, std) { alias core.stdcpp.vector.std.vector vector; alias core.stdcpp.string.std.string string; ... } ---module user- import stl; std.vector v; std.string s;
Re: extern(C++, ns)
Dne 20.1.2016 v 23:01 Walter Bright via Digitalmars-d napsal(a): > I understand his suggestion. I asked Manu to elaborate what the "serious > problems" are. This code snippet doesn't work as it is not supposed to > work, but still unknown is what the "serious problem" with it is - and I > want to ensure that Manu knows this is not a bug in the implementation. Bugs in implementation are a separate concern. The "serious" problem is that the decision to have a namespace introduce a new scope needlessly complicates writing D-like interfaces to C++ code, while catering for one specific use-case that is considered niche. Everything in this thread has been repeated at least three times. Yet you still stand by your design decision and offer more or less convoluted ways to deal with it. I guess that at this point it would be great to introduce some hard data. For example, how often would you encounter the problem with the same identifiers distinguished by namespaces, if you tried to interface to some typical C++ libraries. Because, unless you really must have your interface in one file, this should be fairly rare (at least from my experience). Martin
Re: extern(C++, ns)
On 21 January 2016 at 06:56, Walter Bright via Digitalmars-dwrote: > On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: >> >> -- name.x.d >> module name.x; >> -- name.y.d >> module name.y; >> import name.x; >> extern(C++, name) int x; >> > > > This won't work any more than: > > import name.y; > struct name { } > > would. You can't have two different definitions for the same identifier in > the same scope, and that's true for any programming language I've heard of. Of course. But I don't know how you keep missing my point; I didn't declare something called 'name', I declared something called 'x'. I don't want this namespace called 'name'; I didn't declare it, and it causes problems, like this. The obvious response is "well don't declare it then", but that's not an option we're allowed. I want to opt-out of the namespace. I'd prefer the default was to opt-in though. >> >> extern(C++, delegate) int x; >> > > > Yes, we've talked about that. I'm thinking of a solution where it could be > written like: > > extern(C++, delegate_) int x; > > and the C++ name mangler strips off any trailing _. It's a solution I guess... I wouldn't call it intuitive. Why would someone reading the code expect that behaviour? But again, it's completely unnecessary. I don't want a namespace called 'delegate'. I don't want to declare any D identifier anywhere called 'delegate', I just want it to mangle 'x' properly. You're proposing a work-around to a problem that shouldn't exist in the first place. The proper solution is to make the problem not exist. > Note that this problem is NOT resolved by your proposed solution, as this > wouldn't work, either: > >extern(C++) int* delegate(); >> You claim this is a problem that must desperately be solved: >> >> int x; >> extern(C++, ns) int x; >> >> >> The solution arrives at basically the same problem: >> >> int ns; >> extern(C++, ns) int x; >> >> >> We've just robbed peter to pay paul? > > > C++ doesn't allow: > > int ns; > namespace ns { ... } > > either, so there can never be a need to solve that problem. I'm declaring 'x', not 'ns'. using the namespace to resolve conflict in the first case just creates a second potential for conflict. It's kicked the can, and hasn't reliably solved the problem. Name conflict resolution and name mangling are separate issues, it's no good to conflate them. I'd rather resolve the conflict in a normal D way like any normal D user would. I can best choose how to resolve the conflict with consideration for the case, and this issue has nothing to do with name mangling. >> scanning reflection >> needs to be retrofit with new tricks to recurse into namespaces: >> >> extern(C++, ns) void f(); >> pragma(msg, __traits(allMembers, mixin(__MODULE__))); >> >>> >>> tuple("object", "ns") >> >> >> ... f() is not present. >> >> By extension of this, extern(C++, ns) declarations are incompatible >> with every single implementation of scanning reflection I've written >> in the past 6 years, and everyone else's too. >> All such code needs to be retrofit with new tricks to recurse into ns. > > > Seems to me that all that is necessary is to replace: > > __traits(allMembers, mixin(__MODULE__)) > > with: > >getAllMembersIncludingNs(mixin(__MODULE__)) > > and then write getAllMembersIncludingNS() as a function that recursively > adds members of namespaces. After all, the ugly __traits() was always meant > to be a building block to be encapsulated by a function that does what is > really wanted. I wouldn't call it tricky. ">> All such code needs to be retrofit with new tricks to recurse into ns." I understand I can correct the situation by changing the code, but there is an awful lot of reflection code that already exists, mostly in libraries. Normal programmers don't tend to change library code, they just assume that it doesn't work. You guys hate breaking code, I'm surprised you're not more upset by this. I'm frustrated by the other cases, because you're making me to do work and waste time here complaining about a problem that simply shouldn't exist in the first place. This is the one that really upsets me though. I don't want the namespace to exist. I just want extern(C++, "ns") to take a string, not make a scope, every single problem is solved, and you'll not hear from me for another 6 months.
Re: extern(C++, ns)
On 21 January 2016 at 01:32, Simen Kjaeraas via Digitalmars-dwrote: > On Wednesday, 20 January 2016 at 12:47:44 UTC, Manu wrote: > > 2. Multiple modules cannot have the same name in D. I'm not sure what situation you're imagining where modules would be created with the same names...? >>> >>> How do you plan to map C++'s standard lib ? One giant hundred of >>> thousands of line C++ file ? >> >> >> Surely it would map by file. >> >> #include -> import stl.vector; >> #include -> import stl.map; >> #include -> import stl.string; >> >> Perhaps 'stl' may be something else, 'std' is an unfortunate conflict with >> phobos, but this is unique to this case. > > > I believe deadalnix here meant something like this: > > import stl.vector; > import mylib.vector; > > Vector a; // Ambiguous: could be from mylib or stl > stl.Vector b; // Error: no such class stl.Vector > stl.vector.Vector c; // Works, but requires extra typing Okay let me tweak your code: import stl.vector; import stl.string; // one more thing; when do you ever only import a single module? import mylib.vector; Vector a; // Ambiguous: could be from mylib or stl stl.Vector b; // Error: this wouldn't work, becase stl could be stl.vector.stl or stl.map.stl stl.vector.Vector c; // This is what a D programmer expects, exactly like every other conflict resolution in D ever, but it doesn't work either So, it is proposed that people desire to type only stl.Vector to disambiguate, assuming that 'stl' is a named namespace. This only works in the rare case that you only import one single module. This is almost never true! As soon as you import 2 modules, stl.vector, stl.string for instance, 'stl' is now in conflict, and you require to type: stl.vector.stl.Vector c; // Necessary, and even more extra typing! I am yet to experience a single case of isolated imports... real code that's not a 3 line test case tends to import more than one thing. I also object strongly to the rules being different than every other case of conflict in D that a user has ever experienced. > Which with working namespaces might allow case b to work. I hope I've shown how it almost never does, and only makes the situation worse.
Re: extern(C++, ns)
On 1/20/2016 3:12 PM, Martin Drašar via Digitalmars-d wrote: The "serious" problem is that the decision to have a namespace introduce a new scope needlessly complicates writing D-like interfaces to C++ code, while catering for one specific use-case that is considered niche. Adding a qualifier here and there does not count as serious.
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 05:32:08 UTC, Walter Bright wrote: Actual code examples of the serious problems would be appreciated. All the namespace code examples you posted were bugs that have since been fixed, or were misunderstandings that were explained. IMO his description was already quite clear, but here you are: // a.d module a; extern(C++, ns) { void fooa(); void bar(); } // b.d module b; extern(C++, ns) { void foob(); } void bar(); // main.d import a, b; void main() { fooa(); // ok foob(); // ok bar(); // Error: b.bar at b.d(6) conflicts with a.ns.bar at a.d(5) // let's try to disambiguate: we want ns.bar ns.bar(); // Error: a.ns at a.d(3) conflicts with b.ns at b.d(3) a.ns.bar(); // works, but requires superfluous `a`, even though // `ns` already makes it unambiguous } Of course, it's because of how name lookup works in D, and we understand that. But it still diminishes the usability of this feature considerably, as the above situation is extremely likely to run into if you're porting a sufficiently large C++ library.
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 16:38:19 UTC, Marc Schütz wrote: // a.d module a; extern(C++, ns) { void fooa(); void bar(); } // b.d module b; extern(C++, ns) { void foob(); } void bar(); // main.d import a, b; void main() { fooa(); // ok foob(); // ok bar(); // Error: b.bar at b.d(6) conflicts with a.ns.bar at a.d(5) // let's try to disambiguate: we want ns.bar ns.bar(); // Error: a.ns at a.d(3) conflicts with b.ns at b.d(3) a.ns.bar(); // works, but requires superfluous `a`, even though // `ns` already makes it unambiguous } I think the first error is correct: bar(); // Error: b.bar at b.d(6) conflicts with a.ns.bar at a.d(5) So you have two functions bar() one inside 'ns' in module a and "outside" 'ns' in module b. Now, the last 2 errors, Mark Schutz said: a.ns.bar(); // works, but requires superfluous `a`, even though // `ns` already makes it unambiguous Question: What happens if you do this: using "ns1" in "module a" and "ns2" in "module b" and do: ns1.bar(); ? Because you can't have more than one namespaces with the same name in C++, right? JohnCK.
Re: extern(C++, ns)
On 1/20/2016 1:47 PM, Timon Gehr wrote: On 01/20/2016 09:56 PM, Walter Bright wrote: On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: -- name.x.d module name.x; -- name.y.d module name.y; import name.x; extern(C++, name) int x; This won't work ... The suggestion was to just not introduce a new symbol/scope for the namespace. It would certainly work. I understand his suggestion. I asked Manu to elaborate what the "serious problems" are. This code snippet doesn't work as it is not supposed to work, but still unknown is what the "serious problem" with it is - and I want to ensure that Manu knows this is not a bug in the implementation.
Re: extern(C++, ns)
On 1/20/2016 8:38 AM, Marc Schütz wrote: IMO his description was already quite clear, but here you are: What's missing is why this is a *serious* problem. All you've got to do is add a qualifier.
Re: extern(C++, ns)
On Tuesday, 19 January 2016 at 21:40:01 UTC, Walter Bright wrote: Please do not conflate not agreeing with my answers with not responding. I am not claiming that you weren't participating in the discussion threads or something like that. But in all your arguments you seem to presume that (badly) imitating the scoping semantics of C++ namespaces in D is somehow a given, that it is natural and does not need justification. However, my position is (Manu and Daniel would probably agree) that this is not a valid assumption. To add a new feature to the language, the onus is on you to provide compelling evidence why it is necessary to have. You need to show that there is a "serious problem" with just using the native D namespacing scheme (modules) for the purpose, not the other way round. — David
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 20:56:49 UTC, Walter Bright wrote: On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: You claim this is a problem that must desperately be solved: int x; extern(C++, ns) int x; The solution arrives at basically the same problem: int ns; extern(C++, ns) int x; We've just robbed peter to pay paul? C++ doesn't allow: int ns; namespace ns { ... } either, so there can never be a need to solve that problem. In Manu's example, `int ns` is a native D variable, not an extern(C++) one. The C++ code you responded with has no relevance to whether Manu's example could or should work; it's entirely determined by the design of the D compiler. More generally, the basic purpose of `extern(C++)` is simply to indicate that a D identifier should be mapped to a certain C++ symbol. It makes no sense to insist that the D identifier *must* be derived from the C++ symbol in a some specific way (that is, by including the C++ namespace in the D identifier) to make the problem tractable. If you wanted to, you could easily make the mapping totally arbitrary with something like `pragma(mangle)`. Given that the mapping could be anything you choose, how can D's identifier disambiguation facilities be adequate for native D symbols, and yet not for C++ symbols? Why must there be any difference between the two at all?
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 22:13:09 UTC, Walter Bright wrote: You can always write a module that all it does is import a bunch of other modules, with a bunch of aliases which can be used to make those imports appear in another namespace: module core.stdcpp.vector extern (C++, std) { struct vector { } } module core.stdcpp.string extern (C++, std) { struct string { } } module stl-- private import core.stdcpp.vector; private import core.stdcpp.string; ... extern (C++, std) { alias core.stdcpp.vector.std.vector vector; alias core.stdcpp.string.std.string string; ... } ---module user- import stl; std.vector v; std.string s; The thought of needing to do that for (potentially) every single symbol being imported is depressing. What happened to DRY?
Re: extern(C++, ns)
On Tuesday, 19 January 2016 at 21:46:07 UTC, Walter Bright wrote: On 1/19/2016 12:35 PM, David Nadlinger wrote: You'd run into all kinds of weird issues, as Manu pointed out – many of which have hopefully been fixed by Walter in the meantime. Please read the thread. I fixed them and posted here that they were fixed. Please do not conflate implementation bugs with the design. Before making such statements, it might be prudent to somewhat thoroughly read the message you are referring to. The sentence immediately before the one you quoted reads: "At least when this thread was started, it was not at all possible to just blissfully ignore them." I am not conflating implementation and design – in fact I was precisely pointing out to to Chris that part of the troubles Manu was having is due to implementation issues! — David
Re: extern(C++, ns)
On 21 January 2016 at 08:01, Walter Bright via Digitalmars-dwrote: > On 1/20/2016 1:47 PM, Timon Gehr wrote: >> >> On 01/20/2016 09:56 PM, Walter Bright wrote: >>> >>> On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote: -- name.x.d module name.x; -- name.y.d module name.y; import name.x; extern(C++, name) int x; >>> >>> >>> This won't work ... >> >> >> The suggestion was to just not introduce a new symbol/scope for the >> namespace. >> It would certainly work. > > > I understand his suggestion. I asked Manu to elaborate what the "serious > problems" are. This code snippet doesn't work as it is not supposed to work, > but still unknown is what the "serious problem" with it is - and I want to > ensure that Manu knows this is not a bug in the implementation. I know it's not a bug in the implementation, it's a bug in the DESIGN. I don't want the namespace scope. My problem and every other problem except the interface inheritance one, is instantly solved. I consider this inability to opt-out when confronted with this set of problems I've shown to be a 'serious' usability problem. Surely the existence of this thread demonstrates that... you understand that if the namespace scope never existed, this entire thread and every problem that I've had would have never existed?
Re: extern(C++, ns)
On 21 January 2016 at 08:15, Walter Bright via Digitalmars-dwrote: > On 1/20/2016 8:38 AM, Marc Schütz wrote: >> >> IMO his description was already quite clear, but here you are: > > > What's missing is why this is a *serious* problem. All you've got to do is > add a qualifier. It's 'serious' in that my cases are very highly likely; almost guaranteed to occur, indeed they occurred within minutes of my test-driving this feature. The design has a very high probability of inhibiting usability, and I can't imagine a real-world situation where it improves usability. I've tried to demonstrate some practical and very likely occurring cases which show that the design isn't correct; I have hit all of them. I just want to opt-out. I don't want to hear about workarounds... I don't want to explain the various workarounds to other people when they encounter these problems that there's no reason for them to encounter in the first place. I don't want name conflict resolution to behave in a special way because the .lib file happened to be compiled by a C++ compiler. I just want to tell the name mangler the C++ namespace, and let me get back to writing D code. Every single problem I've had with extern(C++, ns), and continue to have, is solved by not emitting a namespace scope, and I can't imagine a case where it will help me. Seriously, I'm not exaggerating here. The design does not carry its weight.
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 23:35:31 UTC, Manu wrote: On 21 January 2016 at 01:32, Simen Kjaeraas via Digitalmars-dwrote: On Wednesday, 20 January 2016 at 12:47:44 UTC, Manu wrote: 2. Multiple modules cannot have the same name in D. I'm not sure what situation you're imagining where modules would be created with the same names...? How do you plan to map C++'s standard lib ? One giant hundred of thousands of line C++ file ? Surely it would map by file. #include -> import stl.vector; #include -> import stl.map; #include -> import stl.string; Perhaps 'stl' may be something else, 'std' is an unfortunate conflict with phobos, but this is unique to this case. I believe deadalnix here meant something like this: import stl.vector; import mylib.vector; Vector a; // Ambiguous: could be from mylib or stl stl.Vector b; // Error: no such class stl.Vector stl.vector.Vector c; // Works, but requires extra typing Okay let me tweak your code: import stl.vector; import stl.string; // one more thing; when do you ever only import a single module? import mylib.vector; Vector a; // Ambiguous: could be from mylib or stl stl.Vector b; // Error: this wouldn't work, becase stl could be stl.vector.stl or stl.map.stl stl.vector.Vector c; // This is what a D programmer expects, exactly like every other conflict resolution in D ever, but it doesn't work either [snip] Which with working namespaces might allow case b to work. I hope I've shown how it almost never does, and only makes the situation worse. I'm playing devil's advocate here, since I fully agree with you that there is absolutely no need for C++ namespaces in D, and that the cost in language complexity is too high. Suppose that case b above worked, though - instead of a conflict, lookup would basically merge namespaces with the same name, and only conflict if there are multiple definitions that are not namespaces. On the one hand, I hope that's how it's supposed to work, otherwise it's just silly. On the other hand, that's a clear break with D's current lookup rules, and for what I consider very, very little benefit. -- Simen
Re: extern(C++, ns)
On Tuesday, 19 January 2016 at 22:14:42 UTC, Walter Bright wrote: 1. C++ has namespaces. They went and invented a whole 'nother thing called modules. Evidently not even they think that modules and namespaces are the same thing. C++ modules (as per N4465, etc.) are a whole different story and entirely unrelated to the discussion. Their existence is neither an argument for or against having extern(C++) create named scopes for namespaces. 2. Multiple modules cannot have the same name in D. C++ practice is to litter code with namespaces using the same name. If you want to split up the interface to a C++ namespace among different modules, then the different symbols will *always* reside in different fully qualified scopes – with or without additional scopes being introduced by extern(C++)! The fact that modules are "sealed" scopes is an integral part of the D module system, and while your statement is true, I'm not sure how it constitutes an argument for having extern(C++) introduce more scopes in addition to that. 3. Modules have ModuleInfos, static constructors/destructors, etc. These do not make obvious sense for namespaces. How does this apply to the discussion? Again, extern(C++) code lives inside a D module either way. […] Actually, I'll skip commenting on the other points for now, because reading your last paragraph makes me suspect that there is a misunderstanding: I.e. if modules were bludgeoned into being namespaces, there would be such a list of special cases and confusions and exceptions and awkward crap you'd be far, far better off having namespace as a SEPARATE feature, because that's what they'd wind up being anyway, even if they were named "modules". From this statement, it seems as if you think we are arguing for modules somehow being mapped directly to C++ namespaces, in the vein of some hypothetical "module(C++, ns) foo;" declaration. However, this is not the case at all. Quite the contrary, my proposal (and, as far as I understand also that of Manu, Daniel and others who have agued against your design) is that C++ namespaces should have no semantic representation on the D side at all. We like our D modules as they are [1], and we are certainly not trying to bludgeon them into any other shape. Given the vast semantical differences between them and C++ namespaces – and you haven't even really mentioned the extensibility aspect and the new inline namespaces in your list – this would be a foolish thing to do. Modules only enter the picture in so far as they provide a natural way for client code of two C++ library wrappers to disambiguate between two symbols that have the same name, as it might happen if they correspond to C++ symbols from different namespaces. In other words, modules would likely quite often happen to provide the necessary means of disambiguation, because one would put the wrappers for two different C++ namespaces into different D modules anyway. But if you wanted to have, say, two declarations for interfacing with both A::foo() and B::foo() within the same D module, you could always use another of D's scoping mechanism for that, like (mixin) templates or whatever else tickles your fancy [2]. — David [1] That is, except for issue 314 and the visibility vs. accessibility problem. [2] Those scopes might of course currently leak into the C++ mangled name – I didn't check –, but this can be fixed.
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 07:51:27 UTC, Manu wrote: 1. C++ has namespaces. They went and invented a whole 'nother thing called modules. Evidently not even they think that modules and namespaces are the same thing. You admit that modules supersede namespaces. We have modules, we use modules as standard practise. We don't need, or want, anything like namespaces. Maybe you don't, but I remain quite confident that being able to mimic the structure of the C++ code in D is valuable. One can create a binding for a library and have it usable in a similar fashion as it is in C++ from D. This makes it nice to people that already know the library, reduce the need for specific doc for the binding, and makes maintenance of the binding much easier as it has the same structure as the mapped C++ lib. 2. Multiple modules cannot have the same name in D. I'm not sure what situation you're imagining where modules would be created with the same names...? How do you plan to map C++'s standard lib ? One giant hundred of thousands of line C++ file ? 4. Modules and files have a 1:1 correspondence. This does not work for namespaces. I'm not sure what your point here is. Are you arguing that C++ namespaces aren't expressible in D, because nothing can span modules? Of course, I agree completely. This is a good argument against trying to simulate C++ namespaces in D. That doesn't make any sense. 5. "extern (C++) module std" ? Ugh. Where did you pull that from? Nobody has ever suggested anything like that as far as I know. Naturally, I strongly object to this too. Well you still have to explain how the C++'s standard library is going to be mapped with D module emulating C++'s namespaces. 7. Module semantics are independent of where they are imported. Not so for namespaces. I.e. if modules were bludgeoned into being namespaces, Nobody has ever suggested anything like this. You did that quite a few time yourself. there would be such a list of special cases and confusions and exceptions and awkward crap you'd be far, far better off having namespace as a SEPARATE feature, because that's what they'd wind up being anyway, even if they were named "modules". If this is what you're thinking, you've misunderstood literally everything I've ever said on this topic. The feature should be nothing more than this: extern(C++, "ns") int x; x is mangled with "ns". Namespace is a string, no conflict with D names is possible, organisation and disambiguation is the business of the author. Everything past that is needless complexity and causes us problems. The extremely niche case where someone wants to declare 2 symbols with the same name within the same module (in C++, they achieve this using 2 namespaces), is easily solvable in various ways that a normal D user could use to resolve that desire in a pure D program, for instance (but not limited to) putting the second declaration in another module. The WHOLE point of namespace in C++ is to be able to have symbol with the same name and not conflict. Now you could say, put them in different modules and use the modules to disambiguate, but then you'd use the C++ library in quite a different way, meaning you need to write new doc and make the work of the binding maintainer harder. _all consequent problems_ are abolished instantly, all behaviour is exactly like normal D code, no surprises, no edge cases. The code to do this must be a small fraction of the code required to implement the feature as it is today. I don't expect so. All the resolution mechanisms required here already exists in some form already. DMD may be kludged, but come on, once something is defined a way, it is not possible to change it, so please disregard DMD specificity here.
Re: extern(C++, ns)
On 1/19/2016 11:51 PM, Manu via Digitalmars-d wrote: You admit This is where a debate about ideas leaves the rails. This is not a court, nobody has alleged a crime. I want to bring it back on the track. I want to help you be successful with interfacing D with C++. You have posted several bugs with the ns implementation. I have fixed those bugs, and you agreed they were fixed. You wrote there are remaining serious problems with ns. I have no idea what they are. Please post code that illustrates what serious problem(s) you are having.
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 08:38:35 UTC, Walter Bright wrote: On 1/19/2016 11:51 PM, Manu via Digitalmars-d wrote: You admit This is where a debate about ideas leaves the rails. This is not a court, nobody has alleged a crime. I want to bring it back on the track. I want to help you be successful with interfacing D with C++. You have posted several bugs with the ns implementation. I have fixed those bugs, and you agreed they were fixed. You wrote there are remaining serious problems with ns. I have no idea what they are. Please post code that illustrates what serious problem(s) you are having. Considering all the arguments both recently and when the feature was first implemented, I find it unlikely that everyone will ever agree to one solution. Are there any strong arguments against making the scope *optional*? The cost of implementation should be quite low, both compared to the complexity of the feature itself and the complexity of all the *different* workarounds people already use to hide the symbols.
Re: extern(C++, ns)
On 20 January 2016 at 18:38, Walter Bright via Digitalmars-dwrote: > On 1/19/2016 11:51 PM, Manu via Digitalmars-d wrote: >> >> You admit > > > This is where a debate about ideas leaves the rails. This is not a court, > nobody has alleged a crime. I want to bring it back on the track. > > I want to help you be successful with interfacing D with C++. You have > posted several bugs with the ns implementation. I have fixed those bugs, and > you agreed they were fixed. > > You wrote there are remaining serious problems with ns. I have no idea what > they are. Please post code that illustrates what serious problem(s) you are > having. I'm blocked by the interface inheritance. I can work-around anything other than that, but there's no way I can progress without being able to call methods. This set of related problems, all have bitten me. -- name.x.d module name.x; -- name.y.d module name.y; import name.x; extern(C++, name) int x; extern(C++, delegate) int x; You claim this is a problem that must desperately be solved: int x; extern(C++, ns) int x; The solution arrives at basically the same problem: int ns; extern(C++, ns) int x; We've just robbed peter to pay paul? Finally, the one that really upsets me, is that scanning reflection needs to be retrofit with new tricks to recurse into namespaces: extern(C++, ns) void f(); pragma(msg, __traits(allMembers, mixin(__MODULE__))); > tuple("object", "ns") ... f() is not present. By extension of this, extern(C++, ns) declarations are incompatible with every single implementation of scanning reflection I've written in the past 6 years, and everyone else's too. All such code needs to be retrofit with new tricks to recurse into ns. On 20 January 2016 at 18:38, Walter Bright via Digitalmars-d wrote: > On 1/19/2016 11:51 PM, Manu via Digitalmars-d wrote: >> >> You admit > > > This is where a debate about ideas leaves the rails. This is not a court, > nobody has alleged a crime. I want to bring it back on the track. > > I want to help you be successful with interfacing D with C++. You have > posted several bugs with the ns implementation. I have fixed those bugs, and > you agreed they were fixed. > > You wrote there are remaining serious problems with ns. I have no idea what > they are. Please post code that illustrates what serious problem(s) you are > having. >
Re: extern(C++, ns)
On Wednesday, 20 January 2016 at 12:47:44 UTC, Manu wrote: No, I really *really* didn't. It seems I have a habit of being completely misunderstood. Just for your information, I understand what you mean Manu :) (and agree with you). I guess it might be helpful if you could spell out (in pseudo code) how you would wrap part of the c++ std library (std.vector and std.map?) in your proposed way and how you have to do it now. This might help to highlight your point.
Re: extern(C++, ns)
On 20 January 2016 at 18:37, deadalnix via Digitalmars-dwrote: > On Wednesday, 20 January 2016 at 07:51:27 UTC, Manu wrote: >>> >>> 1. C++ has namespaces. They went and invented a whole 'nother thing >>> called modules. Evidently not even they think that modules and namespaces >>> are the same thing. >> >> >> You admit that modules supersede namespaces. We have modules, we use >> modules as standard practise. >> We don't need, or want, anything like namespaces. >> > > Maybe you don't, but I remain quite confident that being able to mimic the > structure of the C++ code in D is valuable. One can create a binding for a > library and have it usable in a similar fashion as it is in C++ from D. How is that not possible with normal use of modules? > This makes it nice to people that already know the library, reduce the need > for specific doc for the binding, and makes maintenance of the binding much > easier as it has the same structure as the mapped C++ lib. I'm not sure how maintaining this structure has anything to do with namespaces. The only requirement for a lib to feel natural is to map each header to a module of the same name. When I look up the qt doc, I see: #include Which intuitively maps to: import qt.widget; The author requires some latitude in such mapping, eg: #include Obviously unsavoury in D mapped verbatim, it would likely become: import sdl.image; You may consider this a drastic deviation from the doc, but I expect D users would universally prefer this. >>> 2. Multiple modules cannot have the same name in D. >> >> >> I'm not sure what situation you're imagining where modules would be >> created with the same names...? >> > > How do you plan to map C++'s standard lib ? One giant hundred of thousands > of line C++ file ? Surely it would map by file. #include -> import stl.vector; #include -> import stl.map; #include -> import stl.string; Perhaps 'stl' may be something else, 'std' is an unfortunate conflict with phobos, but this is unique to this case. >>> 7. Module semantics are independent of where they are imported. Not so >>> for namespaces. >>> >>> I.e. if modules were bludgeoned into being namespaces, >> >> >> Nobody has ever suggested anything like this. >> > > You did that quite a few time yourself. No, I really *really* didn't. It seems I have a habit of being completely misunderstood. > The WHOLE point of namespace in C++ is to be able to have symbol with the > same name and not conflict. D is extremely good at this already. > Now you could say, put them in different modules and use the modules to > disambiguate, but then you'd use the C++ library in quite a different way, > meaning you need to write new doc and make the work of the binding > maintainer harder. This doesn't make sense at all. How is that using it in a completely different way? I'd suggest it's the only possible way to make it feel the same. It's a no-brainer for the binding author, copy and rename .h files to .d, then regex until finished. What case is there where a C++ lib distributing its symbols naturally among modules named accordingly with the original include's would cause confusion when compared against the C++ docs? Doc says '#include ', I'll 'import libname.feature;' Nothing could be more natural than this. As a bonus, the project's C++ namespace 'libname' is already present in the fully qualified name, it's the top level package! No point repeating that as 'libname.feature.libname.symbol'.
Re: extern(C++, ns)
On 1/19/2016 12:42 AM, Daniel Murphy wrote: So Why make extern(C++, namespace) introduce a new symbol? Why not just let it change ONLY mangling and use modules to organize symbols and resolve conflicts? 1. Because a namespace is a scope, and is expected to act like one. 2. So names in different namespaces will not conflict. 3. So names in namespaces can be referenced as: std.exception as one would expect. As the length of this thread testifies, this has been discussed at length already.
Re: extern(C++, ns)
On 18/01/2016 6:47 AM, Walter Bright wrote: > On 1/17/2016 3:55 AM, Daniel Murphy wrote: >> So now we have two public symbols called 'mylib', and because they >> conflict they >> can't be used to disambiguate eg 'someotherlib.funca' with >> 'library.a.funca'. > > Consider these two C++ files: > > --file 1- > namespace (X) { int fooa() { ... } > --file 2- > namespace (X) { int fooa() { ... } > - > > You'll get a multiply defined symbol error for X.fooa() from the linker. > When using namespaces in D, the "one definition rule" needs to be > followed just as in C++ for the same reason. > > However, in D, you CAN do the following: > > -module M--- > extern (C++,X) { int fooa(); } > -module N--- > extern (C++,X) { int fooa(); } > > > and yes, M.X.fooa() will wind up referring to the same externally > defined symbol X::fooa() as N.X.fooa(). > > Because, as I said multiple times, namespaces in D affect the name > mangling in a C++ way while doing symbol lookup in the D way. > > Note that > > extern(C) { ... } > > in D works EXACTLY the same way. So Why make extern(C++, namespace) introduce a new symbol? Why not just let it change ONLY mangling and use modules to organize symbols and resolve conflicts?
Re: extern(C++, ns)
On 18/01/2016 12:19 PM, Chris Wright wrote: On Sun, 17 Jan 2016 22:55:23 +1100, Daniel Murphy wrote: So now we have two public symbols called 'mylib', and because they conflict they can't be used to disambiguate eg 'someotherlib.funca' with 'library.a.funca'. Users want to disambiguate between a use of C++ namespace members and other values from other modules. The natural way to do this is to provide a fully qualified D name. For instance, if I wrapped C++ type Urho3D::Core::Context in D module urho3d.core, I'd normally refer to it as urho3d.core.Context. That works today. It's got no problems. However, in your scenario, users don't want to use the D module names to disambiguate. They want to use C++ namespaces. Why? IMO the only reason to use C++ namespaces in D is to match mangling of a C++ library you want to link to. If they just changed mangling and nothing else, then they would do their job just fine.