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