April 04, 2014
On Friday, 4 April 2014 at 12:34:15 UTC, Dicebot wrote:
> Late to the thread, my short opinion:
>
> extern(C++ namespace::path) looks best. It should only affect mangling and have no impact on fully qualified name on D side. Most KISS solution I have read in the thread.

I actually remember almost trying this syntax before reading this thread.  It's definitely intuitive, and it KIS.  Though, may I suggest

extern(C++, namespace::path) or
extern(C++, namespace, path)

keeping in line with __traits and pragma?
April 04, 2014
On 03.04.2014 00:07, Walter Bright wrote:
> Here's Andrei's proposal:
>
>      extern (C++) template nspace() {
>          int foo();
>      }
>
> It would be accessed in D by:
>
>     nspace!().foo();
>
> A possible enhancement would be to allow (for all templates with no parameters):
>
>      nspace.foo();
>
> Note that:
>
>      template nspace() {
>          extern (C++) int foo();
>      }
>
> would not put foo() in a C++ namespace, although it would still be accessed from
> D as:
>
>      nspace.foo();
>
> One downside of this proposal is that if we ever (perish the thought!) attempted
> to interface to C++ templates, this design would preclude that.

I have to say I like Robert Clipsham's idea best:

extern(C++) module nspace {
    int foo(); // Is this also extern(C++)? I think it should be.
}

extern(C++) module nspace {
    module innernspace {
        int bar(); // Also extern(C++), if we follow the example above.
    }
}

I haven't the foggiest idea how C++ modules are supposed to work, so there might be clashes with those somehow?

-- 
  Simen
April 04, 2014
On Friday, 4 April 2014 at 18:51:21 UTC, Simen Kjærås wrote:
> I have to say I like Robert Clipsham's idea best:
>
> extern(C++) module nspace {
>     int foo(); // Is this also extern(C++)? I think it should be.
> }
>
> extern(C++) module nspace {
>     module innernspace {
>         int bar(); // Also extern(C++), if we follow the example above.
>     }
> }

All solutions based on binding extern(C++) to some D qualification entity are bad because they confuse reader into thinking that `bar` is actually `nspace.innerspace.bar` and that should never happen.
April 04, 2014
On 04.04.2014 20:54, Dicebot wrote:
> On Friday, 4 April 2014 at 18:51:21 UTC, Simen Kjærås wrote:
>> I have to say I like Robert Clipsham's idea best:
>>
>> extern(C++) module nspace {
>>     int foo(); // Is this also extern(C++)? I think it should be.
>> }
>>
>> extern(C++) module nspace {
>>     module innernspace {
>>         int bar(); // Also extern(C++), if we follow the example above.
>>     }
>> }
>
> All solutions based on binding extern(C++) to some D qualification entity are
> bad because they confuse reader into thinking that `bar` is actually
> `nspace.innerspace.bar` and that should never happen.

I'm not entirely sure I follow you here. Is this what you mean?

extern(C++) module nspace {
    int foo();
}

void main() {
    foo();        // Either this does not work, (#1)
    nspace.foo(); // or this does not work.     (#2)
}

If so, is that really bad? I'd say the better choice is to make #2 work, as then #1 can be made to work with a simple alias:

alias foo = nspace.foo;

If I'm far off into the fields of ignorance now, care to show me the way to a better understanding?

-- 
  Simen
April 04, 2014
On 4/4/2014 5:34 AM, Dicebot wrote:
> Late to the thread, my short opinion:
>
> extern(C++ namespace::path) looks best. It should only affect mangling and have
> no impact on fully qualified name on D side. Most KISS solution I have read in
> the thread.

Fails because:

C++:

    namespace S { namespace T {
        int foo();
        namespace U {
            int foo();
        }
     } }

D:

  extern (C++, S::T) {
      int foo();
      extern (C++, U) {
        int foo();
      }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


April 04, 2014
On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:
>   foo();  // error, ambiguous, which one?
>   S.T.foo(); // S undefined

I want explicit namespaces "S::T::foo()".
April 04, 2014
On 4/4/2014 1:00 PM, "Ola Fosheim Grøstad" <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> I want explicit namespaces "S::T::foo()".

We already have a scope operator, '.', don't need another one.
April 04, 2014
On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:
> C++:
>
>     namespace S { namespace T {
>         int foo();
>         namespace U {
>             int foo();
>         }
>      } }
>
> D:
>
>   extern (C++, S::T) {
>       int foo();
>       extern (C++, U) {
>         int foo();
>       }
>   }
>   foo();  // error, ambiguous, which one?
>   S.T.foo(); // S undefined

Why would we need new ways of declaring scopes in D? Overriding the external mangling should be sufficient? If there are collisions you can use any type of scope you prefer to avoid the issue, modules, structs, templates, even functions or blocks...

void fun1() { extern (C++, S::T) int foo();}
void fun2() { extern (C++, S::T::U) int foo();}

extern (C++, S::T::U) int foo();
struct test { extern (C++, S::T) int foo();}
April 04, 2014
On Friday, 4 April 2014 at 20:06:49 UTC, Walter Bright wrote:
> We already have a scope operator, '.', don't need another one.

It is more clear to the reader that it is an external namespace and you avoid renaming because then C++ has it's own namespace in D reducing the chances of clashes. But it's a minor issue, although I think it is important for long term maintainability of code to easily discriminate between C++ function calls (which tend to be supportive lower level libraries/engines) and D function calls (which tend to be higher level code).

When you do contract work on many projects for different small businesses, you often get requests for modifications/additions 1-2 times a year or so. The less chance of code misinterpretation, the better.
April 04, 2014
Tove:

> Why would we need new ways of declaring scopes in D? Overriding the external mangling should be sufficient? If there are collisions you can use any type of scope you prefer to avoid the issue, modules, structs, templates, even functions or blocks...
>
> void fun1() { extern (C++, S::T) int foo();}
> void fun2() { extern (C++, S::T::U) int foo();}
>
> extern (C++, S::T::U) int foo();
> struct test { extern (C++, S::T) int foo();}

This seems promising, but this idea needs to become simpler.

Bye,
bearophile