April 28, 2014
On Mon, 28 Apr 2014 10:00:56 -0400, Ola Fosheim Grøstad <ola.fosheim.grostad+dlang@gmail.com> wrote:

> On Monday, 28 April 2014 at 13:47:43 UTC, Steven Schveighoffer wrote:
>> Not ok. This is like having 2 definitions for the same function, linker will not accept that.
>
> No. It is like having 2 matching type declarations. The implementation is defined in the C++ source code and is represented as one C++ object/lib file to the linker. The linker will happily accept that.

Oh sorry, in my head, I was sure they each had implementations ;)

Yeah, I think that should work just fine.

I see now where your objection is. I think either the rule needs to be better explained, or that it is incorrect.

-Steve
April 28, 2014
On Monday, 28 April 2014 at 14:08:56 UTC, Steven Schveighoffer wrote:
> I see now where your objection is. I think either the rule needs to be better explained, or that it is incorrect.

I think so too, because if my undestanding is correct then it will discourage writing libs in mixed D/C++ and encourage writing libs in pure C++.

Basically turning D into an application level language (on the level of Objective-C so to speak)?
April 28, 2014
On Sun, 27 Apr 2014 15:54:51 -0400, Walter Bright <newshound2@digitalmars.com> wrote:

> http://wiki.dlang.org/DIP61

I think there is a big problem with name lookup here.

Consider this code:

module foo;

void func() {}

module bar;

extern(C) func();

module prog;

import foo;
import bar;

void main()
{
   func(); // error
   foo.func(); // ok
   bar.func(); // ok, uses C binding (no name mangling)
}

In this case, even though the C function is not mangled or in any other namespace, the module can be used for unambiguous calling.

But in your proposal, the name qualifiers could be either C++ namespaces or D modules. This presents an unnecessary ambiguity.

e.g.

module foo;

void func() {}

module bar;

extern(C++, foo) void func(); // foo::func in C++ land

module prog;

import foo;
import bar;

void main()
{
   func(); // error
   foo.func(); // ALSO error
   bar.func(); // Not error, BUT it's actually calling foo::func from C++ land!
}

I think we cannot change name lookup rules for C++ symbols, because the D module system already owns those.

An alternative is that you could create an alternate way to disambiguate. Let's pick a strawman called _cpp, just to illustrate:

void main()
{
   func(); // error still
   foo.func(); // calls D's foo module's func
   bar.func(); // calls D's bar module's func (defined as foo::func)
   _cpp.func(); // error, _cpp denotes we are using namespace qualifiers, and there is no global C++ func
   _cpp.foo.func(); // calls D's bar module's func.
   bar._cpp.foo.func(); // ditto
}

Really, _cpp could be anything. But I think hijacking D's module qualifiers does not help. To make things seamless, you could make it ::, but I know many people have objections to that.

-Steve
April 28, 2014
On Mon, 28 Apr 2014 10:27:19 -0400, Steven Schveighoffer wrote:

> On Sun, 27 Apr 2014 15:54:51 -0400, Walter Bright <newshound2@digitalmars.com> wrote:
> 
>> http://wiki.dlang.org/DIP61
> 
> I think there is a big problem with name lookup here.
> 
> Consider this code:
> 
> module foo;
> 
> void func() {}
> 
> module bar;
> 
> extern(C) func();
> 
> module prog;
> 
> import foo;
> import bar;
> 
> void main()
> {
>     func(); // error foo.func(); // ok bar.func(); // ok, uses C binding
>     (no name mangling)
> }
> 
> In this case, even though the C function is not mangled or in any other namespace, the module can be used for unambiguous calling.
> 
> But in your proposal, the name qualifiers could be either C++ namespaces or D modules. This presents an unnecessary ambiguity.
> 
> e.g.
> 
> module foo;
> 
> void func() {}
> 
> module bar;
> 
> extern(C++, foo) void func(); // foo::func in C++ land
> 
> module prog;
> 
> import foo;
> import bar;
> 
> void main()
> {
>     func(); // error foo.func(); // ALSO error bar.func(); // Not error,
>     BUT it's actually calling foo::func from C++
> land!
> }
> 
> I think we cannot change name lookup rules for C++ symbols, because the D module system already owns those.
> 
> An alternative is that you could create an alternate way to
> disambiguate.
> Let's pick a strawman called _cpp, just to illustrate:
> 
> void main()
> {
>     func(); // error still foo.func(); // calls D's foo module's func
>     bar.func(); // calls D's bar module's func (defined as foo::func)
>     _cpp.func(); // error, _cpp denotes we are using namespace
>     qualifiers,
> and there is no global C++ func
>     _cpp.foo.func(); // calls D's bar module's func.
>     bar._cpp.foo.func(); // ditto
> }
> 
> Really, _cpp could be anything. But I think hijacking D's module qualifiers does not help. To make things seamless, you could make it ::, but I know many people have objections to that.
> 
> -Steve

why not  import _cpp = bar;   ?

April 28, 2014
On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:

>
> why not  import _cpp = bar;   ?

That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup.

Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used!

-Steve
April 28, 2014
On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote:

> http://wiki.dlang.org/DIP61

Would nesting imported namespaces work?

lib/package.d
public
export(C++, a) {
  public import lib.b;

}


lib/b.d
export(C++, b) {
  void foo();
}

main.d
import lib;
a.b.foo();


April 28, 2014
On Mon, 28 Apr 2014 10:45:14 -0400, Steven Schveighoffer wrote:

> On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:
> 
> 
>> why not  import _cpp = bar;   ?
> 
> That doesn't help. foo.func() is still ambiguous. With this proposal, you have hijacked the meaning of namespace lookup. When I say x.y.z, it doesn't just mean look for symbol z in module x/y.d, it can also mean to look for symbol z in C++ namespace x::y. This was not the case with C binding, which continued to use D modules for symbol lookup.
> 
> Consider that a boatload of C++ code is named std::something. Now, std.string has an ambiguous meaning wherever it is used!
> 
> -Steve

bar is renamed, thus you have to access via _cpp.[namespace] renames were added to prevent hijacking.
April 28, 2014
On Mon, 28 Apr 2014 10:50:09 -0400, Byron <byron.heads@gmail.com> wrote:

> On Mon, 28 Apr 2014 10:45:14 -0400, Steven Schveighoffer wrote:
>
>> On Mon, 28 Apr 2014 10:37:36 -0400, Byron <byron.heads@gmail.com> wrote:
>>
>>
>>> why not  import _cpp = bar;   ?
>>
>> That doesn't help. foo.func() is still ambiguous. With this proposal,
>> you have hijacked the meaning of namespace lookup. When I say x.y.z, it
>> doesn't just mean look for symbol z in module x/y.d, it can also mean to
>> look for symbol z in C++ namespace x::y. This was not the case with C
>> binding, which continued to use D modules for symbol lookup.
>>
>> Consider that a boatload of C++ code is named std::something. Now,
>> std.string has an ambiguous meaning wherever it is used!
>>
>> -Steve
>
> bar is renamed, thus you have to access via _cpp.[namespace]
> renames were added to prevent hijacking.

That renames the bar module, but not the foo C++ namespace, which can be assumed when calling foo.func.

In reality, you could "fix" the situation by renaming the foo D module, and then foo.func would unambiguously refer to bar's func :)

Another alternative fix would be to allow renaming C++ namespaces. I strongly recommend against that. The better alternative is to reserve qualified name lookup to D modules alone. Adding a mechanism that is possibly ugly, but that does NOT conflict with module lookup, in order to disambiguate C++ symbols is fine.

-Steve
April 28, 2014
On Mon, 28 Apr 2014 10:46:33 -0400, Byron <byron.heads@gmail.com> wrote:

> On Sun, 27 Apr 2014 12:54:51 -0700, Walter Bright wrote:
>
>> http://wiki.dlang.org/DIP61
>
> Would nesting imported namespaces work?
>
> lib/package.d
> public
> export(C++, a) {
>   public import lib.b;
>
> }
>
>
> lib/b.d
> export(C++, b) {
>   void foo();
> }
>
> main.d
> import lib;
> a.b.foo();

Most definitely no. When the compiler builds b.d, he has no idea it's imported from inside another namespace! We don't want #include-style issues.

-Steve
April 28, 2014
On Monday, 28 April 2014 at 14:54:17 UTC, Steven Schveighoffer wrote:
> Adding a mechanism that is possibly ugly, but that does NOT conflict with module lookup, in order to disambiguate C++ symbols is fine.

Requiring C++ identifiers to be fully qualified with "::" would solve that and encourage writing thin idiomatic D wrappers on top of C++ libs.

(and cause a lot of complaints from C++ programmers :-)