Is there any good reason why C++ namespaces are "closed" in D?

Manu turkeyman at gmail.com
Tue Jul 31 08:12:01 UTC 2018


On Mon, 30 Jul 2018 at 23:15, Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> My issue is you're presenting solutions. But I have no idea what the problem is,
> because every time I present a solution to the examples you give, you say it's
> no good, because your problem is something else.

I'm not asking for workarounds or 'solutions'. I know the workarounds
very well, because I've been writing them repeatedly for years. I want
to see this mistake corrected.
It's not a case of "can't do the thing", this is a case of "i hate
doing the thing (ie, workarounds), the results are particularly
unsatisfying, and the whole basis for the problem is unfounded".

We repeat it over and over.
The case on trial today is that it can't be 'reopened', which is
awkward in cases of generative programming (like Atila's case), and is
a conversation that shouldn't even need to exist; a namespace given
for mangling doesn't exhibit this issue.
We can't specify some valid C++ namespace names that are D keywords.
(also, 'std' is particularly annoying, since it conflicts with phobos)
Other cases where it conflicts with itself when you import 2 modules
with symbols spanning the same namespace, which is more common than
not. The resolution is explicit disambiguation using the D module
scope (which is the whole point of D modules), and so the C++
namespace scope is just redundant.

Given your favourite example:
----
module a;
extern(C++, ns) void foo();
----
module b;
extern(C++, ns) void foo();
-----
module c;
import a, b;
foo(); // error: ambiguous
ns.foo(); // error, ambiguous (obviously)
a.ns.foo(); // naturally, this works... it's the D module that
correctly organises the symbol. 'ns' is worthless here

Just like every other instance in D code ever where modules are used
to organise symbols.
I don't have to convince you that D modules work well... you need to
convince us that D modules are insufficient.

ns is just annoying complexity, and it interferes with other code.
Atila's thing about 'reopening' namespaces is a non-issue if namespace
was just for mangling. The whole class of problem ceases to exist. (I
have been frustrated by this same problem too)
Scanning meta doesn't have to learn to identify and recurse into C++
namespaces to traverse that edge case where a module has some C++
symbols. No scanning meta every written is equipped with that logic.
There's no advantage to the ns scope, and it only brings challenges.
None of any of our time ever needed to be wasted here. The feature as
designed absolutely has not solved any form of problem. It has not
saved more time than it's wasted, and it never will.

Not to mention that it's ugly and leads to undesirable and unintuitive
symbol names.
When a C++ namespace spans modules (ie, the C++ namespace encloses the
whole library's api), translation to D looks like this:

module ns.submodule;
extern(C++, ns) void foo();

The name is:
ns.submodule.ns.foo(); // <- ns is already present at the head of the
qualified name, there's no point repeating it.


The converse case where modules are divided by their namespace (which
naturally maps to D modules):

module cpplib.ns;
extern(C++, ns) void foo();

Now the name is:
cpplib.ns.ns.foo(); // <- why would anyone want that?


In both cases it's just a repeat of what's already in the module name.
But the redundancy is more than a nuisance in certain forms of scanning meta.

And got forbid the case where C++ namespaces are embedded (namespace
for lib name, another for the module), and we have this:

module lib_ns.module_ns;
extrern(C++, lib_ns) extern(C++, module_ns) void foo();

The name is:
lib_ns.module_ns.lib_ns.module_ns.foo(); // <- ....words can't even


> My second point is that changing the language is a last resort solution, not a
> first resort.

This isn't a last-resort, this was truly a first-resort... I started
making this noise within some number of hours after the appearance of
the design countable on my fingers. (far less aggressively, having not
spent years of my life stewing on this)
You've just blocked the conversation for sufficiently long that now
you're able to say that sentence you just said. Was that a deliberate
strategy? I feel like that strategy's been used before.

That said, I'm not proposing a language 'change', we can just support
a string version in parallel and everything's fine if we don't want to
deprecate the scope version.


> Thirdly, C and C++ are loaded to the gills with
> seemed-like-a-good-idea-at-the-time solutions that turned out to have bad
> unintended consequences that bork up the language for everyone down the line. D
> has some of those, too.

extern(C++, ns) is the poster child of exactly that.
In this case, it seemed-like-a-good-idea to one person and was
implemented with no consultation of anyone. The design was never
presented or scrutinised. It just merged, and when we promptly
complained, our criticism were rejected on principle.
Maybe we should write up a retro-DIP, and see if it passes review...?


> Forgive me, but:
>
>     extern (C++, "ns")

It should be a string such that valid C++ namespace names that are
grammatically invalid in the extern expression aren't arbitrarily
rejected.


> has a definite smell about it of something going awry, and the idea that it
> shouldn't introduce a scope because nobody relies on C++ namespaces being in a
> scope despite that being the whole point of namespaces is a giant red flag of
> something terribly wrong somewhere.

C++ programmers depend on namespaces to scope stuff _in C++_.
D programmers depend on modules to scope stuff (and it's a much better
solution).
Why don't you have faith in using modules to scope stuff? It's been
working well for us all this time. People don't often complain that
they have trouble scoping things intelligently in D.

You need to argue a reason for the complexity, it's not my job to
argue against the complexity that shouldn't ever have existed.
Justifying the complexity is your burden of proof; it was never
discussed or proven out.
I can't argue my case any more than I have, but you haven't argued
yours at all other than a feeling that is 'smells', and a sense of red
flag that the D module system, which works perfectly fine in general,
has some inexplicable weakness in this one case for some reason that's
never been identified.

You fear an unjustified torrent of bug reports if we were to fix this,
but you don't acknowledge the constant stream of bug reports with the
design as-is. You've got this backwards.


More information about the Digitalmars-d mailing list