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

Rubn where at is.this
Fri Aug 3 22:55:51 UTC 2018


On Friday, 3 August 2018 at 21:20:37 UTC, Walter Bright wrote:
> On 8/2/2018 2:26 AM, Daniel N wrote:
>> Personally I would never *bind* to two different namespaces in 
>> a single file,
>
> You'd be amazed at what people do and then set their entire 
> store based on it. If the language spec allows it, people will 
> do it. People will even design their code to require certain 
> bugs in the compiler. (This really blows when you're trying to 
> write a standard compliant C/C++ compiler and you get angry 
> letters from customers about why I'm not supporting some stupid 
> bug in BrandX C++ that they rely on.)
>
> One of my favorite stories about this was a company that had a 
> coding style where their comments looked like this:
>
>     //******** text ********\\
>
>     int x;
>
> They thought it was marvelous! But what really happens when 
> you've got two line concatenation characters at the end? Is one 
> line concatenated, or two? You have to carefully read the spec 
> to determine which, and it matters because if two are 
> concatenated then the declaration of x vanishes. And BrandX did 
> it wrong, the customer wrote all their code this way, and it 
> all broke with my compiler, and of course it was all my fault.
>
> I thought "who in their right mind would write code that way?" 
> At least I could justify myself with BrandX is a buggy 
> compiler, but when the behavior is in the spec, I have no leg 
> to stand on.

A simple regex could have fixed that problem. They dug themselves 
a hole and if they don't want to support other compiles, then 
they will be stuck with BrandX.

> If we want to support interfacing with C++, we have to support 
> badly written C++, because that is the NORMAL case. Telling 
> them their code is **** and that they should rewrite it in 
> order to work with D is never, ever going to work.

There seems to be a misunderstanding here, you don't have to 
rewrite the C++ code. Merely the D code has to be formatted 
differently. Unless you have some obsession with maintaining 1:1 
C++ and D code. Which is not a technical problem, but one of 
organization. D isn't C++ and trying to do something crazy like 
make it compatible so that the files are 1:1 is crazy and 
unachievable. It only causes problems like what we have now. 
Maintaining a 1:1 correlation isn't on most D users that work 
with C++ wish list. Hell all of the Derelict libraries don't 
maintain a 1:1 at all.

> Another anecdote - Microsoft MASM in the 80's was full of bugs. 
> I mean full of bugs. When Borland came out with an assembler, 
> it wouldn't work with most of the ASM files out there. They 
> finally had to engineer in what they called "quirks mode" to 
> emulate MASM's bugs. Telling customers to rework their ASM 
> files didn't work for a large company, either.

The difference is they would have to rework their existing code. 
If you are writing D source code bindings for your code, then you 
are essentially writing new code. You don't have to worry about 
backwards compatibility.

Not only that, who do you think even writes bindings for 
libraries? Most bindings are done by the community for libraries 
to other languages. How many companies do you know have bindings 
for their C/C++ libraries for D, that maintains them?

>> are there any other additional benefits to the current design 
>> which I'm overlooking?
>> 
>> With a non-scoped extern(c++) we could simply use two files.
>
> Yes. But then you'll have the people who want a 1:1 
> correspondence with their C++ files and the corresponding D 
> files. I happen to be one of those people, for the ease of 
> maintaining a translation (and for comparing it with the 
> original C++ source code if it is not behaving correctly).
>
> Besides, I provided solutions for both Manu's case and Atila's 
> (they are different), which are easier than "simply" breaking 
> things up into multiple files.

So why can't you define the same namespace twice in the same 
module? There was some conflict that didn't allow it to be 
implemented the same way as in C++ or something right. So why try 
to imitate C++ in D but fail to do so because D isn't C++. I 
think it's worse to try to imitate namespaces in D then create 
these exceptions to rules when you get snagged on a limitation.

Imagine someone tried to write a DIP to add namespaces into D. Do 
you think anything like that would ever be accepted? God damn 
hell no. That's what modules are for. So why are you trying to 
implement namespaces in D under the guise of C++ name mangling. 
What extern(C++) should be used for is allowing you to call C++ 
code from D, not to be able to format C++ code into D. The only 
problem you have with breaking code up into multiple files is 
that it isn't 1:1. That's not a technical problem, it's a problem 
of conflicting personal opinion. If it's not 1:1, who cares? If 
some some odd reason you have two namespaces in one file in C++, 
odds are they are probably separated in that one file anyway. If 
not and for some reason the the code has multiple namespace 
definitions smashed together into one file, flip-floping between 
namespaces. That's not D's problem to fix the project's poor 
organization method. Modules are a better way of doing things, we 
shouldn't be promoting C++'s mistakes in D.


>> My conclusion is that _if_ I understood you correctly, it must 
>> mean that in the examples which you have in mind, it is common 
>> to *bind* to two namespaces in the same file? Could you give a 
>> real-world examples of two namespaces which you would like to 
>> mix like that in the same *bindings* file? Is it for instance 
>> 'std' and 'std::experimental'?
>
> In D it is not allowed to have multiple modules in the same 
> file. This can become deeply entrenched in the way one thinks 
> about programming, to the point where one cannot conceive of 
> doing it other ways, i.e. ways that C++ allows, and that I 
> believe are poor practice, but people do anyway.
>
> You can see this in the C++ backend. It is certainly not 
> organized in a module-like manner. (It predates C++ namespaces, 
> so doesn't use them.)


On Friday, 3 August 2018 at 21:49:53 UTC, Walter Bright wrote:
> > I mean `std` should never be part of the fully qualified name
> of, for
> > instance, `core.stdcpp.exception.std.bad_exception`. It
> should just
> > be `core.stdcpp.exception.bad_exception` instead.
>
> C++ recognizes that, too, which is why it has "using" 
> declarations. D has the equivalent thing, "alias".
>
> You can do things like:
>
>     import std = core.stdcpp.exception;
>
> and then refer to:
>
>     std.bad_exception
>
> or:
>
>     import exception = core.stdcpp.exception;
>
>     exception.bad_exception;
>
> or whatever works best for one's project. Aliasing and import 
> renaming (which are really just more aliasing) is very capable, 
> and was designed for just these sorts of issues.

Until you want to use more than one module it falls flat on it's 
face:

import std = core.stdcpp.exception;
import std = core.stdcpp.vector; // as an example future use

// can't have both, error: import "std" conflicts with other 
import "std"
std.bad_exception
std.vector!int




More information about the Digitalmars-d mailing list