DIP61: redone to do extern(C++,N) syntax

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 29 17:41:59 PDT 2014


On Tue, 29 Apr 2014 17:38:07 -0400, Timon Gehr <timon.gehr at gmx.ch> wrote:

> On 04/29/2014 10:49 PM, Steven Schveighoffer wrote:
>> On Tue, 29 Apr 2014 16:00:43 -0400, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>
>>> On Tue, 29 Apr 2014 15:52:01 -0400, Walter Bright
>>> <newshound2 at digitalmars.com> wrote:
>>
>>>> Because the compiler would now issue an error for that, it's its
>>>> anti-hijacking feature.
>>>>
>>>> Try it and see!
>>>
>>> I agree! that was my central point, which Timon seemed to be arguing
>>> against :)
>>
>> And in fact, so were you!
>> ...
>>
>> This is EXACTLY the same code that you said would now be an error above!
>
> Maybe he didn't notice that you changed the 'main' function relative to  
> my post. If you don't mention 'foo' explicitly, then obviously it cannot  
> be hidden by the import and the code is in error.

I never changed the code. It always was foo.func(). That was my point.

>
>>
>> I think you guys  need to reexamine this,
>
> Not me. I typically test my claims even if I am sure, if only to file  
> bug reports.

Your view has been consistent. I think it defeats the purpose of having  
namespaces to disambiguate calls, since the disambiguation itself  
conflicts with modules.

If foo.func means one thing today and another thing tomorrow, based on an  
import, I think the feature is flawed. Template namespaces are just as  
flawed.

>
>> and choose one way or another.
>> At this point, I have no clue as to how it's supposed to work.
>>
>
> Obviously you did not actually try. :P

No, I get what you are saying. The above statement is because I'm getting  
conflicting reports from Walter.

> Again, to make it really easy for you to test the behaviour:
>
> module foo;
> import std.stdio;
>
> int func(){ writeln("hello from foo!"); return 1; }
>
> //---
>
> module bar;
> import std.stdio;
>
> mixin template X(){
>      int func(){ writeln("hello from bar!"); return 2; }
> }
> mixin X foo;
>
> //---
>
> module prog;
>
> void main(){
>      void onlybar(){
>          import bar;
>          auto r=foo.func(); // hello from bar!
>          assert(r==2); // pass!
>      }
>      void fooandbar(){
>          import bar,foo;
>          auto r=foo.func(); // hello from foo!
>          assert(r==1); // pass!
>      }
>      onlybar();
>      fooandbar();
> }

Wouldn't a similar test be to create a struct for a namespace?

The confusing issue here to C++ programmers is, when I specify x::y::z, it  
means z in namespace x::y, regardless of where it was imported. If in D we  
say you can access this via x.y.z, they are going to think they can always  
type that. To have it so easily break is not a good thing.

>
>
> http://dlang.org/download.html
>
> $ dmd prog foo bar && ./prog
> hello from bar!
> hello from foo!
>
> This is because the import of module 'foo' hides the namespace 'foo'  
> imported from 'bar' in the scope of 'fooandbar'. It is not 'func' that  
> is being hidden, but 'foo'.

In fact, it's the entire foo namespace.

module bar;

import std.stdio;

mixin template X(){
     int func(){ writeln("hello from bar!"); return 2; }
     int func2(){ writeln("hello also from bar!"); return 2;} // no  
equivalent in foo.d
}
mixin X foo;

module foo; // same as before
...

module prog;
import foo; // comment out to compile
import bar;

void main()
{
    foo.func2(); // Error: undefined identifier 'func2', did you mean  
'function func'?
}

So basically any namespace that matches the root phobos import path will  
cause conflicts. You don't suppose any C++ code uses that do you? ;)

-Steve


More information about the Digitalmars-d mailing list