April 04, 2014
On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:
> 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

I don't feel this is a problem. Such foo's should be disambugated by D tools, which means using different modules. Exact matching between C++ and D sources is impossible anyway, it is not worth complicating D qualification system for that.
April 04, 2014
On Friday, 4 April 2014 at 19:33:34 UTC, Simen Kjærås wrote:
> 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?

#2 should not compile. D currently does not have any notion of namespaces other than modules / aggregates and I am against introducing those just for the sake of interfacing with C++.
April 04, 2014
On Friday, 4 April 2014 at 21:39:01 UTC, bearophile wrote:
> 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

This seems like it would be simple if it came with a recommended style for library wrappers, e.g.

// C++
namespace A {
  namespace B {
    void f1();
    void f2();
  }
  namespace C {
    void f3();
    void f4();
  }
}

// D
struct A {
  struct B {
  extern(C++, A, B):
    static void f1();
    static void f2();
  }
  struct C {
  extern(C++, A, C):
    static void f3();
    static void f4();
  }
}

This can be easily generated by hand or with something like SWIG, and keeps the semantics of "extern" consistent throughout the language (it still only affects the ABI).  This also keeps things simple for users who just want to call one function.

// D
void callF1() {
  extern(C++, A, B) void f1();
  f1();
}

I used "," instead of "::" because it avoids adding a new token, but that's more of an aesthetic issue.
April 04, 2014
On Friday, 4 April 2014 at 07:06:30 UTC, Walter Bright wrote:
> On 4/3/2014 5:47 PM, deadalnix wrote:
>> I'm not familiar with usual C++ mangling as much as D. Are
>> template and namespace mangled the same way ?
>
> No.

Then that is a bad idea.
April 04, 2014
On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:
> On Friday, 4 April 2014 at 19:33:34 UTC, Simen Kjærås wrote:
>> 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?
>
> #2 should not compile. D currently does not have any notion of namespaces other than modules / aggregates and I am against introducing those just for the sake of interfacing with C++.

templates, function bodies, block statements, ...
April 05, 2014
On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:
> #2 should not compile. D currently does not have any notion of namespaces other than modules / aggregates and I am against introducing those just for the sake of interfacing with C++.

If you want to interface with C++ you should do it well or not at all. In C++ namespace names reside in their own namespace which means that you get short names like "std", "qt" etc. Which in turn means you have to rename those to "CPPstd", "CPPqt" etc in D in order to disambiguate the symbols. Having a dedicated namespace operator would be a lot more convenient.
April 05, 2014
On Saturday, 5 April 2014 at 08:42:27 UTC, Ola Fosheim Grøstad wrote:
> On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:
>> #2 should not compile. D currently does not have any notion of namespaces other than modules / aggregates and I am against introducing those just for the sake of interfacing with C++.
>
> If you want to interface with C++ you should do it well or not at all. In C++ namespace names reside in their own namespace which means that you get short names like "std", "qt" etc. Which in turn means you have to rename those to "CPPstd", "CPPqt" etc in D in order to disambiguate the symbols. Having a dedicated namespace operator would be a lot more convenient.

D has own tools to disambugate symbols. Introducing new ones is equivalent to admitting D module system does not work by design.
April 05, 2014
On Saturday, 5 April 2014 at 12:07:36 UTC, Dicebot wrote:
> D has own tools to disambugate symbols. Introducing new ones is equivalent to admitting D module system does not work by design.

I think it is primarily a notation issue. Should the notation help you discern what is C++ and what is D, or do you have to memorize symbols? How much extra notational work is it acceptable to impose on the programmer?

There are advantages and disadvantages to both approaches.

Pro explicit c++ namespaces:

- Easy to discern what is C++ and what is D.

- Less chance of future irreconcilable design conflicts when either C++ or D changes (e.g. C++18 and beyond)

- Having a philosophy of "native foreign functions" rather than "masquerading as D constructs" makes it easier to integrate with other languages beyond c/c++ at a later stage.

Con:

- More syntax to understand for newbies

- Requires a little bit more refactoring when moving C++ code to D.
April 05, 2014
On Saturday, 5 April 2014 at 12:30:28 UTC, Ola Fosheim Grøstad wrote:
> Should the notation help you discern what is C++ and what is D, or do you have to memorize symbols? How much extra notational work is it acceptable to impose on the programmer?

It shouldn't. The fact how entity is exposed via some external binary interface should not have any notable impact on D side of things (unless you dwell into ABI realm). This is exactly what "extern" is for - matching symbols from domain of D terms to some external alien domain.
April 05, 2014
On Saturday, 5 April 2014 at 12:58:54 UTC, Dicebot wrote:
> It shouldn't. The fact how entity is exposed via some external binary interface should not have any notable impact on D side of things (unless you dwell into ABI realm).

This is a design philosophical issue, you can make it normative if you want, but only if it is consistent with the overall design philosophy.

Working on making that philosophy explicit is important, D2 is showing some signs of having gone through a lot of evolutionary design and IMHO signs of a need for notational redesign. Meaning: recreate the syntax to fit the desired semantics that the language has obtained over time (as in designing it, not evolving).

Not distinguishing between C++/D does however have consequences: if foreign constructs have the same appearance as the language constructs then you should also make sure that all the semantics are the same. E.g. C++ exceptions, calls to C++ new etc have to be fully harmonized with D equivalents.