On 2014-04-03 03:48:18 +0000, Walter Bright <newshou...@digitalmars.com> said:
On 4/2/2014 7:14 PM, Michel Fortin wrote:
That's a contrived example.
Not at all. The whole point of using namespaces in C++ is to introduce
a scope. And the whole point of scopes is to have the same name in
different scopes represent different objects.
Perhaps I'm wrong, but I'd assume the general use
case is that all functions in a module will come from the same C++ namespace.
I believe that is an incorrect assumption. C++ namespaces were
specifically (and wrongly, in my not so humble opinion, but there it
is) not designed to be closed, nor have any particular relationship
with modules.
Alternatively you can use another module for the other namespace.
Forcing C++ code that exists in a single file to be split up among
multiple D files is inflicting unnecessary punishment on the poor guy
trying to justify migrating to D.
Ok, let's assume that we actually want to reproduce the C++ file
structure then. Let us have a C++ project, with two files. I'll
temporarily use the 'namespace' keyword on the D side until we can
decide on how to best represent a namespace:
module foo;
extern (C++):
namespace S { namespace T {
int foo();
namespace U {
int foo();
}
} }
module bar;
extern (C++):
namespace S { namespace T {
int bar();
namespace U {
int bar();
}
} }
Now let's use those:
module main;
import foo;
import bar;
void main() {
S.T.foo();
S.T.U.bar();
}
But how does the lookup for those functions work? If we use structs or
templates to represent those namespaces in D then you'll have to
specify the module name to disambiguate the struct/template itself, and
the namespace just becomes a nuisance you have to repeat over and over:
void main() {
.foo.S.T.foo();
.bar.S.T.U.bar();
}
Here I'd argue that having whole-module namespaces in D makes no sense.
So let's retry by peeling the "S.T" part of the namespace:
module foo;
extern (C++, S.T):
int foo();
namespace U {
int foo();
}
module bar;
extern (C++, S.T):
int bar();
namespace U {
int bar();
}
module main;
import foo;
import bar;
void main() {
foo();
.bar.U.bar();
}
Better. Still, if you want C++ namespaces to work nicely, you'll have
to introduce first class namespace support in D. That means that
identical namespaces are "merged" into each other when you import
modules that contain them. It'd allow you to write this:
void main() {
foo();
U.bar();
}
Still, I'm not convinced that'd be terribly helpful. Namespaces in D
would make it easier to declare things 1:1 for sure, but anything that
depends on Koenig lookup[1] will be broken in D. It could even be
silently broken as no Koenig lookup means another function not in a
namespace could be used silently instead of the expected one in a
namespace (assuming a naive port of some C++ code).
[1]: https://en.wikipedia.org/wiki/Argument-dependent_name_lookup
I'd tend to simply implement extern(C++, namespace.here), which should
work fine to wrap single-namespace cpp files, and wait to see what are
the actual friction points before introducing more (people can
experiment with structs or other modules meanwhile).
--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca