April 05, 2014
On 4/5/2014 2:55 PM, Michel Fortin wrote:
> I like this idea. But... should this potentially useful thing really be
> restricted to extern C++ things? I've seen at least one attempt to create a
> namespace using what D currently offers [1], and frankly something like the
> above would make much more sense than a class no one can instantiate.

I can't escape the feeling that if you're trying to do namespaces in D, you're doing something worng.

I feel that C++ messed up namespace design because:

1. namespaces are not closed
2. they have no relationship with modules

which has wound up forcing the addition of Yet Another Design when imports and modules are added to C++.

April 05, 2014
Michel Fortin:

> Here's a suggestion:
>
> 	@namespace A.B { // can create two levels at once, yeah!
> 		void foo();
> 		void bar();
> 	}
> 	@namespace C {
> 		void foo();
> 	}
>
> Make those C++ declarations, it does not look too foreign anymore:
>
> 	extern (C++) @namespace A.B {
> 		void foo();
> 		void bar();
> 	}
> 	extern (C++) @namespace C {
> 		void foo();
> 	}

I suggest to keep the access to C++ namespaces as a feature for interoperability only, and to have no namespaces in D.

Bye,
bearophile
April 06, 2014
On 2014-04-05 20:47:32 +0000, Walter Bright <newshound2@digitalmars.com> said:

> Yes, this seems to be a fatal flaw. Another design that has evolved from these discussions and my discussions with Andrei on it:
> 
>      extern (C++, namespace = A.B) { void foo(); void bar(); }
>      extern (C++, namespace = C) void foo();
> 
>      bar();  // works
>      A.B.bar(); // works
>      foo(); // error: ambiguous
>      C.foo();   // works
> 
>      alias C.foo foo;
>      foo();  // works, calling C.foo()

What if you also have a C++ foo at global scope?

	module cpptest;

	extern (C++) void foo();
	extern (C++, namespace = A) void foo();

	foo(); // ambiguous
	A.foo(); // works
	.foo(); // works?
	cpptest.foo(); // works?

Does these two last lines make sense?


-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

April 06, 2014
On 4/5/2014 6:26 PM, Michel Fortin wrote:
> What if you also have a C++ foo at global scope?

It'll work exactly the same as import does.


>      module cpptest;
>
>      extern (C++) void foo();
>      extern (C++, namespace = A) void foo();
>
>      foo(); // ambiguous
>      A.foo(); // works
>      .foo(); // works?

Yes.

>      cpptest.foo(); // works?

Yes.

> Does these two last lines make sense?

Just as much sense as:

    module bar;
    void foo();
    .foo(); // works
    bar.foo(); // works

Namespace lookup rules would be exactly the same as for imports and mixin templates.
April 06, 2014
On 2014-04-05 22:42, Walter Bright wrote:

> 2. C++ namespaces are very low hanging fruit, with a significant payoff.
> It's worthwhile.

I think it's very low hanging fruit to add support for basic C++ namespaces. Support for basically just set the mangled name in a somewhat nice way, a pragma for example. If we're talking about adding something more advanced  like "::" or "extern (C++) template" which my affect the current name look up rules then I don't think that's so low hanging fruit anymore.

-- 
/Jacob Carlborg
April 06, 2014
On Sunday, 6 April 2014 at 02:33:38 UTC, Walter Bright wrote:
> On 4/5/2014 6:26 PM, Michel Fortin wrote:
>> What if you also have a C++ foo at global scope?
>
> It'll work exactly the same as import does.
>
>
>>     module cpptest;
>>
>>     extern (C++) void foo();
>>     extern (C++, namespace = A) void foo();
>>
>>     foo(); // ambiguous
>>     A.foo(); // works
>>     .foo(); // works?
>
> Yes.
>
>>     cpptest.foo(); // works?
>
> Yes.
>
>> Does these two last lines make sense?
>
> Just as much sense as:
>
>     module bar;
>     void foo();
>     .foo(); // works
>     bar.foo(); // works
>
> Namespace lookup rules would be exactly the same as for imports and mixin templates.

My main reservation against the new suggestion is that one would be forced to open a new nested namespace even when it's detrimental, because in some cases the namespace structure is already reflected in the filesystem(just like for D:s module system).

I can't assess how widespread this is globally, but at least some high-quality projects already have guidelines to use file/namespace mappings.

A random example from boost:
boost::asio::ip::multicast
boost/asio/ip/multicast.hpp

One can of course workaround this issue with an extra alias for every imported symbol, or use compile-time reflection to auto-generate all alias statements... (or heaven forbid, put entire boost in one file ;))

I assume the "namespace = xxx" syntax is some sort of named parameter, would it be possible to add another similar param, which only changes mangling and doesn't actually create a new scope?
April 06, 2014
> I think it's very low hanging fruit to add support for basic C++ namespaces. Support for basically just set the mangled name in a somewhat nice way, a pragma for example.

I think it is more important to think in term of strategic positions than whether it takes 1 or 2 weeks to implement a feature.

Assumption:
It is desirable to make the eco system more attractive for commercial projects.

Key requirements:
- Long term stability of the dev environment.
- Access to mature libraries with significant backing (basically C/C++ libraries).
- Easy integration with existing technology and systems (basically C/C++).
- No lock-in (basically C/C++ interop).
- Predictable dev environment that enables precise cost estimates.
- Lowering costs/faster development than the alternatives (more convinient than C/C++)

If you cannot assume that you can utilize a C++ library from D or if you have to assume that using a C++ library might incur a significant interfacing overhead (in terms of programmer's time) then D looks like a more risky proposition.

The key difference between a commercial project and a hobby project is that the hobby project can fully adapt the requirements to the dev environment. A hobbyist game project can settle for a less capable physics engine or create a custom one, for fun. A commercial project will view that as costs that cut into profit margins and  a potential source of failure in the market. That's a good reason to go with C++ instead of D.

From a strategic point of view it is important to fully support those features you claim to support.

If you can claim that interfacing with C++, except for templates, is easy, then you communicate that it is relatively easy to assess project costs. If you only claim that it is possible to interface with some of C++, but that it is kind of difficult under certain  vaguely specified circumstances then I think you should wait until you have a better solution.

What you absolutely don't want is to trick people into thinking that interfacing with C++ is easy, if it isn't, and have them discover that they are better off dumping D and doing it all over in C++.
April 06, 2014
On Saturday, 5 April 2014 at 21:43:03 UTC, Walter Bright wrote:
> On 4/5/2014 2:31 PM, Tove wrote:
>> How could this common pattern look?
>> std::string
>> boost::fun(std::string arg)
>>
>> alias cpp    = extern (C++, namespace = std);
>> alias boost = extern (C++, namespace = boost);
>>
>> cpp.string
>> boost.fun(cpp.string arg)
>>
>> ?
>
> extern (C++, namespace = std) {
>     struct string { ... }
> }
>
> extern (C++, namespace = boost) {
>     void fun(std.string arg);
> }

What would std be here from D's point of view? A module? Or a new kind of symbol?

And wouldn't it clash with D's std package?
April 06, 2014
On 4/6/2014 2:56 AM, "Marc Schütz" <schuetzm@gmx.net>" wrote:
> And wouldn't it clash with D's std package?

Yes. But D has numerous methods of disambiguation.
April 06, 2014
On Saturday, 5 April 2014 at 23:26:30 UTC, Walter Bright wrote:
> I feel that C++ messed up namespace design because:
>
> 1. namespaces are not closed
> 2. they have no relationship with modules

Namespaces are not as powerful as they could have been, but being able to add symbols to an external scope (like classes) is very useful if done right (e.g. cross-cutting enhancements, adding members to external classes like "saveyourself", "printyourself").

> which has wound up forcing the addition of Yet Another Design when imports and modules are added to C++.

Unfortunately that seems to be years into the future? Although clang has begun implementing something:

http://clang.llvm.org/docs/Modules.html

I've got at feeling that if clang gets something working it will become a de-facto standard due to demand.