April 03, 2014
On 4/2/2014 3:33 PM, bearophile wrote:
> I suggest to brainstorm the syntax some more time, because someone could be able
> to invent a better syntax.
>
> Some seeds:
>
> extern (C++(nspace)) {
>      int foo();
> }

I considered that, but it 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


> extern (C++) struct nspace {
>      int foo();
> }

Fails because a struct as struct and struct as namespace are not distinguishable.

April 03, 2014
On 4/2/2014 4:04 PM, Mike wrote:
> Walter, some on this list have not been around long enough to understand the
> motivation for this.  Could you please summarize the problem and how this
> addresses it? Is this for interfacing D to C++, or a way to bring namespace
> semantics to D?


See the earlier thread entitled: "C++ interface." started yesterday.

April 03, 2014
Walter Bright:

> I considered that, but it 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

Then is the idea of "extern(C++) module" by Xiaoxi usable in some way?

Bye,
bearophile
April 03, 2014
On Thursday, 3 April 2014 at 01:06:25 UTC, Walter Bright wrote:
> Because C++ mangles static member functions of structs differently from members of namespaces.

What i meant is not static functions and members of a struct, but a static struct as a concept of a struct, whith can only contain a static stuff. C++ has no such concept, but essentually static struct === namespace.
Consider this:

extern(C++) static struct A {
    static struct B {
        struct X {}
        int foo(X);
    }
}

A.B.foo(A.B.X());
April 03, 2014
Also, D already has scope classes, so why not create full featured class bindings?

Suppose, i have this:

class A {
private:
    int x;

public:
    A(int x_) : x(x_) {}
    A(const A& v) : x(v.x) {}
    ~A() {}
};

Why not interfase those as:

extern (C++) {
    struct A {
        int x;
        this(int x_); // call c++ A::A(int)
        this(this);   // call c++ A::A(const A&)
        ~this();      // call c++ A::~A()
    }
}


I mean, methods in c++ are just like functions in namespaces with first T* argument, so this is also just mangling problem; and all those constructors and destructors are not something special either.

What stops to do that?
If value semantics isn't appropriate, user, who writes D interface can just do it in scope class.
Maby discussing that would also do some good.
April 03, 2014
Or even the simplier way. Just do:

extern(C++) struct A {
    int x;
    A A(int x_);
    A A(ref const(A) v);
    void ~A(A*);
}

And call those methods manually:

A obj = A.A(1);
A obj1 = A.A(obj);
A.~A(&obj);
A.~A(&obj1);

The problem here it to distinguish real static methods from fake ones. But we can actually make user mark real static methods as static.
April 03, 2014
On 2014-04-03 01:09:43 +0000, Walter Bright <newshound2@digitalmars.com> said:

> I considered that, but it 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

That's a contrived example. 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. For the contrived example above, I think it's fair you have to use a contrived solution:

	module s.t;
	extern (C++, S.T):

	int foo();

	struct U {
		static extern (C++, S.T.U):

		int foo();
	}

Alternatively you can use another module for the other namespace.


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

April 03, 2014
On 4/2/2014 7:14 PM, Michel Fortin wrote:
> On 2014-04-03 01:09:43 +0000, Walter Bright <newshound2@digitalmars.com> said:
>> I considered that, but it 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
>
> 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.

> For the contrived example above, I think it's fair you have to use a contrived
> solution:

I don't believe that punishing C++ users who dare to try D is the path to success for D :-)

> 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.
April 03, 2014
On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:
> Here's Andrei's proposal:
>
>     extern (C++) template nspace() {
>         int foo();
>     }

@namespace("nspace")
extern (C++) {
  int 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.

If we have partial C++ bindings, why not have partial template bindings with a subset of features already existing in D? With that you would only need to implement mangling and linking. An interesting and simple enough use case is casting:

extern(C++) T my_cast(T,U)(U);
extern(C++) interface A{}
extern(C++) interface B:A{}

A a;
B b = my_cast!B(a);
April 03, 2014
On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:
> A possible enhancement would be to allow (for all templates with no parameters):
>
>     nspace.foo();

std.string - does it refer to phobos module or C++ string?