<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 3 January 2016 at 15:40, Walter Bright via Digitalmars-d <span dir="ltr"><<a href="mailto:digitalmars-d@puremagic.com" target="_blank">digitalmars-d@puremagic.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On 1/2/2016 8:54 PM, Manu via Digitalmars-d wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
C++ namespacing is causing me endless, and I mean *endless* trouble.<br>
This idea that we express the C++ namespace hierarchy in D is the main problem.<br>
I don't think C++ namespaces should interfere with D scoping rules, they should<br>
be purely for mangling.<br>
It creates a whole bundle of edge cases which either don't have work arounds, or<br>
REALLY awkward workarounds which typically have a heavy impact on all the<br>
regular D code that the C++ code interacts with.<br>
<br>
Not least of which is that C++ namespaces usually span the entire project, and<br>
in D a C++ namespace can only appear in one module ever.<br>
Declaring symbols with the same C++ namespace in different modules leads to<br>
multiple definition errors, and if you are super-careful to avoid those, you<br>
gain name resolution issues in it's place.<br>
</blockquote>
<br></span>
That works the same as in C++. Don't define the same symbol in the same C++ namespace in multiple modules. It doesn't work in C++, and doesn't work in D for exactly the same reason.<br></blockquote><div><br></div><div>I'm not defining the same symbols, I'm defining different symbols, just inside the same namespace.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
It is also very awkward that a C++ namespace can't be the same as a top level<br>
package name. My top level package is named the same as one of my C++<br>
namespaces... what do I do? It gets ugly real fast.<br>
<br>
The main problem extends from this situation:<br>
<br></span><span class="">
module x.y;<br>
<br>
extern(C++, ns) struct Y {}<br>
<br>
<br></span>
module ns.m;<br>
<br><span class="">
import x.y; // fail, the c++ namespace is already present (top level module)<br>
</span></blockquote>
<br>
Doesn't fail when I try it.</blockquote><div><br></div><div>Import another module with the same namespace, have the objects within each instance of the namespace refer to eachother.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
import x.y : Y; // fail, not found<br>
</blockquote>
<br></span>
Again, Y is not module scope.<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
// This **sometimes** works,<br>
</blockquote>
<br>
sometimes?</blockquote><div><br></div><div>Yes, it works sometimes.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
and it's very brittle<br>
</blockquote>
<br></span>
??</blockquote><div><br></div><div>It only 'sometimes' works. Reasons are not clear.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
static import x.y;<br>
alias Y = x.y.Y;<br>
</blockquote>
<br></span>
Nothing wrong with that.</blockquote><div><br></div><div>Except that it doesn't always work.</div><div>It also implies that I must double the number of modules I have, so that I can wrap every module with a C++ namespace in an outer one without it.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Thing is, I'm not declaring a C++ object, I'm declaring a D object,  the only<br>
thing being that struct's take care to maintain common binary layout, and<br>
functions just mangle like C++ so that my code links. I'm in D, I'm declaring my<br>
stuff in the D module where it should be scoped, and where other D code should<br>
expect to find it. I don't see any point in building the C++ hierarchy in this<br>
space. C++ namespace rules are incompatible with D; you can litter them through<br>
C++ code, and add new symbols to C++ namespaces from anywhere...<br>
</blockquote>
<br></span>
You can do that in D as well, as long as you follow the One Definition Rule, which you have to with C++ code anyway.</blockquote><div><br></div><div>It doesn't scale though.</div><div><br></div><div>module x.x;</div><div>import x.y;<br></div><div><br></div><div>extern(C++, ns)</div><div>{</div><div>  class X { Y y; }<br></div><div>}</div><div><br></div><div><br></div><div><div>module x.y;</div><div>import x.x;<br></div><div>extern(C++, ns)</div><div>{</div><div>  class Y { X x; }<br></div></div><div>}</div><div><br></div><div><br></div><div>Error: undefined identifier 'Y'</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
this is<br>
fundamentally incompatible with D, and no further reasoning should be required<br>
to conclude that it can't be reproduced, so it should be for mangling purposes only.<br>
</blockquote>
<br></span>
I guarantee you that if we'd implemented it that way, you'd have a long litany of complaints about that, because the compiler could not distinguish Y from ns.Y.</blockquote><div><br></div><div>You would put it in its own module like normal D code, and let normal D symbol resolution take care of it.</div><div>That's surely the preferred approach anyway? Chances are, your D module structure will match the C++ module structure verbatim anyway, which will have already been structured that way.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I have spent **days**, actually, weeks of my free time trying to make my tiny<br>
bit of code build, and it's just nothing but trouble after trouble. I have<br>
completely restructured my code at least 3 times to try and find a way to make<br>
it fit together in a way that's both practical and works, but I just can't. It<br>
always hits some brick wall somewhere.<br>
<br>
extern(C++, NS) looks okay in isolated tests/experiments, but try and actually<br>
use it, and you will become very frustrated.<br>
<br>
Please, fix this. I'm almost done. I'm really struggling to keep this dream alive.<br>
</blockquote>
<br></span>
I do not understand what difficulty you are having with this.<br>
</blockquote></div><br></div><div class="gmail_extra">It's endlessly difficult, and it's really hard to summarise.</div><div class="gmail_extra"><br></div><div class="gmail_extra">I'm telling you this; as someone who's endlessly fought with this in practical real-world applications, the design is wrong.</div><div class="gmail_extra">D has module scoping, it works, let D's scoping do it's job. This design can lead to nothing but edge cases. We have plenty of edges already.</div><div class="gmail_extra"><br></div><div class="gmail_extra">There was a binary decision made; as far as I know, the decision was made on a whim, there was no design committee, a decision was simply chosen.</div><div class="gmail_extra">I know of no argument that demonstrates that the current state is correct, but I have months of wasted time and energy that prove that it's wrong. Why do I need to now take even more time to construct an elaborate suite of examples to demonstrate my argument?<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">I can't get work done. I've spent all the free time I have trying, and I'd rather write code than spend my time reducing test cases.</div><div class="gmail_extra">Try and bind to a reasonably complex C++ project and you will discover the same thing... or don't, I've honestly already done that work for you!</div><div class="gmail_extra">Please don't make me waste endlessly more of my time, I don't have energy left to spare. This is precisely what's driving me away from D. I can't take it anymore, everything hits brick walls, I am so frustrated, I just want to have a **SINGLE** win, where I can complete a single real-world project and say I have written something that works!</div><div class="gmail_extra"><br></div><div class="gmail_extra">If you're not convinced, then start by fixing the forward referencing issues. They are just bugs, and I highly suspect that many of my tests and experiments have been hindered by the fact that there are actually 2-3 issues working here in tandem. The error messages all look basically the same and offer no help. Forward referencing issue == "undefined identifier", namespace conflict == "undefined identifier". I suspect that cases exist where I was testing one thing, and the other thing jumped in and caused a mis-diagnosis.</div><div class="gmail_extra"><br></div><div class="gmail_extra">That doesn't mean it's not wrong though... let the D module system do what it's designed to do. The point of extern(C++) is to present a C++ API to a D user, so it needs to be arranged in D's terms or the user will feel very uncomfortable, and the author will have to jump through more hoops than if they just stuck with C++.</div></div>