July 30, 2018
On Monday, 30 July 2018 at 02:09:37 UTC, Walter Bright wrote:
> On 7/29/2018 1:52 PM, Manu wrote:
>> On Sun, 29 Jul 2018 at 05:10, kinke via Digitalmars-d
>> <digitalmars-d@puremagic.com> wrote:
>>> [...]
>>> so that a straight C++ namespace => D module hierarchy mapping
>>> would probably be required in the general case:
>>>
>>> ```
>>> // cppns/package.d
>>> module cppns;
>>> extern(C++, "cppns") { void foo(); }
>>>
>>> // cppns/nested/package.d
>>> module cppns.nested;
>>> extern(C++, "cppns") extern(C++, "nested") { void foo(); }
>>> ```
>> 
>> It's beautiful!
>> 
>> (but I added the quotes in there for you; without quotes is existing
>> defined behaviour which introduces scopes)
>> 
>
> But that works now, I suggested it, and you didn't find it acceptable !!?!!

No it doesn't. You missed

>> (but I added the quotes in there for you; without quotes is existing
>> defined behaviour which introduces scopes)

With the above extern(C++, "cppns") (note the quotes) defines the mangling, the D module defines the scope.
This is consistent with e.g. how the druntime bindings to C's standard library (with extern(C)) are used with extern(C) only affects the mangling, not introducing a scope, only that with extern(C++) you can have multiple things in different namespaces all called the same thing, so you actually need the scope as well as the mangling.
July 30, 2018
On Monday, 30 July 2018 at 02:15:57 UTC, Walter Bright wrote:
> On 7/29/2018 1:45 PM, Manu wrote:
>> There's no way you'll get a bug report from someone complaining they
>> can't multiply define symbols in the same scope. That's common sense.
>
> But then you cannot interface with this C++ code:
>
>     namespace ab { void foo(); }
>     namespace cd { void foo(); }
>
> Why would you find this acceptable?

But you can if ab and cd are in different modules. The point is to decouple the mangling from the scope, leave the scope to D's module system, leave the mangling to extern(C++, "foo")
July 30, 2018
On Monday, 30 July 2018 at 02:53:43 UTC, Nicholas Wilson wrote:
> On Monday, 30 July 2018 at 02:15:57 UTC, Walter Bright wrote:
>> On 7/29/2018 1:45 PM, Manu wrote:
>>> There's no way you'll get a bug report from someone complaining they
>>> can't multiply define symbols in the same scope. That's common sense.
>>
>> But then you cannot interface with this C++ code:
>>
>>     namespace ab { void foo(); }
>>     namespace cd { void foo(); }
>>
>> Why would you find this acceptable?
>
> But you can if ab and cd are in different modules. The point is to decouple the mangling from the scope, leave the scope to D's module system, leave the mangling to extern(C++, "foo")

Not that this alleviates Alita's issues at all.
July 29, 2018
On Sun., 29 Jul. 2018, 7:20 pm Walter Bright via Digitalmars-d, < digitalmars-d@puremagic.com> wrote:

> On 7/29/2018 1:45 PM, Manu wrote:
> > There's no way you'll get a bug report from someone complaining they can't multiply define symbols in the same scope. That's common sense.
>
> But then you cannot interface with this C++ code:
>
>      namespace ab { void foo(); }
>      namespace cd { void foo(); }
>
> Why would you find this acceptable?
>

ab.d
------
module ab;
extern(C++, "ab") void foo();


cd.d
------
module cd;
extern(C++, "cd") void foo();



Perfect!


In 20 years, I've never seen 2 namespaces in the same file. And if the C++
code were like that, I'd break it into separate modules anyway, because
that's what every D programmer would expect.
Normal D module divisions map perfectly to every C++ program I've ever
wanted to bind to yet.

Conversely, single namespacs spread across many files appear all the time, and the current solution with disconnected namespaces scoped beneath the modules is extremely un-C++-like and problematic.

> You must have missed my other post:
> [...]

No, I feel like you've missed literally every post I've ever made on the
topic.
We ***do not want to use extern(C++) to scope and organise code***! That's
what modules are for.
D has modules, and they're good, and that's how we want to organise our
code. I feel like I've conveyed that clearly.
It doesn't need to be harder than that. We're perfectly happy with the way
D works in every other case. We don't want 'cases' here.

I can't understand your arguments saying the simpler design (ie, D modules)
are complex, and cause for a torrent of bug reports.
I haven't seen any bug reports about D modules making it impossible to
organise code, and if that were true, then we have a serious problem with
D's module design which carries WAAAY beyond extern(C++).

I understand you're ideologically attached to this idea, and that's fine; I
don't want to take anything away from you.
We have what already exists, that can't go away now, but please just give
us string namespaces as a mangle-only option. Not only will I shut up about
it forever, but we will also be able to specify namespaces that conflict
with D keywords, and also organise our modules just like all other D code
ever.

>


July 29, 2018
On 7/29/2018 7:50 PM, Nicholas Wilson wrote:
> No it doesn't.

I meant that you can today "reopen" namespace scopes by placing them in separate modules.

You can (today) also "reopen" namespace scopes by placing them in separate mixin templates, or struct declarations. I posted examples.
July 29, 2018
On Sun, 29 Jul 2018 at 20:25, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 7/29/2018 7:50 PM, Nicholas Wilson wrote:
> > No it doesn't.
>
> I meant that you can today "reopen" namespace scopes by placing them in separate modules.

That's not the same thing... you can create a _different one_ with the
same name in a different module.
If you import both modules, the namespaces conflict, so it's
definitely not 'reopening' it as such.

You need to make sure to not name the namespace when specifying symbols when you import 2 C++ modules, because it becomes ambiguous.
July 30, 2018
On 7/29/2018 9:53 PM, Manu wrote:
> On Sun, 29 Jul 2018 at 20:25, Walter Bright via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>>
>> On 7/29/2018 7:50 PM, Nicholas Wilson wrote:
>>> No it doesn't.
>>
>> I meant that you can today "reopen" namespace scopes by placing them in separate
>> modules.
> 
> That's not the same thing... you can create a _different one_ with the
> same name in a different module.

That's right, I've said that before, and that's why I put "reopen" in quotes.


> If you import both modules, the namespaces conflict, so it's
> definitely not 'reopening' it as such.

No, they do not conflict. They are qualified by the module name, for exactly the same reason you can have the same name in different modules. And, as I posted before, 'alias' can be used to reference the name(s) as if they were in the current scope.


> You need to make sure to not name the namespace when specifying
> symbols when you import 2 C++ modules, because it becomes ambiguous.

Again, use qualification or an alias, just like is done with D names already.

July 30, 2018
On 7/29/2018 8:05 PM, Manu wrote:
> ab.d
> ------
> module ab;
> extern(C++, "ab") void foo();
> 
> 
> cd.d
> ------
> module cd;
> extern(C++, "cd") void foo();
> 
> Perfect!

  extern(C++, ab) void foo();
  extern(C++, cd) void foo();

Perfect!

  struct S1 { extern(C++, ns) void foo(); } alias foo = S1.ns.foo;
  struct S2 { extern(C++, ns) void bar(); } alias bar = S2.ns.bar;

Perfect!


> We have what already exists, that can't go away now, but please just give us string namespaces as a mangle-only option. Not only will I shut up about it forever, but we will also be able to specify namespaces that conflict with D keywords, and also organise our modules just like all other D code ever.

I'm the one that gets stuck with the fallout from bad designs. The solution I proposed above will work for you as best as I can tell. And it works right now, you don't have to wait for another version.

---

You haven't explained why you can't just move the namespace ns declarations in one file together. C++ code is organized based on the wretched no-forward-references problem which doesn't exist in D.

July 30, 2018
On Monday, 30 July 2018 at 03:05:44 UTC, Manu wrote:
> In 20 years, I've never seen 2 namespaces in the same file. And if the C++
> code were like that, I'd break it into separate modules anyway, because
> that's what every D programmer would expect.

It is common in C++ to have multiple hierarchical namespaces in the same file...


July 30, 2018
On Monday, 30 July 2018 at 08:44:14 UTC, Walter Bright wrote:
>
>   struct S1 { extern(C++, ns) void foo(); } alias foo = S1.ns.foo;
>   struct S2 { extern(C++, ns) void bar(); } alias bar = S2.ns.bar;
>
> Perfect!
>
>

I tried that but it mangles wrong.. it includes "S1" which is not what you want, so I gave up binding to C++ and used C instead.

pragma(msg, foo.mangleof);
_ZN2S12ns3fooEv

Even if it worked, you'd still see the full name in error messages and reflection.

It's much harder to undo parts of one complex operation, compared to composing two simple building blocks. Couldn't we just add a new parameter to control scope or add a pragma or something?