October 10, 2014
On Friday, 10 October 2014 at 22:50:25 UTC, Walter Bright wrote:
> On 10/10/2014 3:20 PM, IgorStepanov wrote:
>>> The same issue also needs to be considered if A and B are structs instead and
>>> B has an additional alias this to an A (the solution might also be part of a
>>> fix for the cycle issue).
>>>
>>> - "If resultSet contains more then one candidates, the compiler raises an error."
>>
>> struct A
>> {
>>    short s;
>>    alias s this;
>> }
>>
>> struct B
>> {
>>    int i;
>>    alias i this;
>> }
>>
>> struct C
>> {
>>    A a;
>>    B b;
>>    alias a this;
>>    alias b this;
>> }
>>
>> long l = C(); //What do you suggest?
>
> The rule would be if:
>
>    long l = C.a();
>    long l = C.b();
>
> both compile, then:
>
>    long l = C();
>
> must be an error, even if one of C.a() or C.b() might be a "better" match. This is how things work for template mixins and imports.
So it is.
October 10, 2014
On Friday, 10 October 2014 at 22:51:34 UTC, Walter Bright wrote:
> On 10/10/2014 3:46 PM, Timon Gehr wrote:
>> On 10/11/2014 12:29 AM, Walter Bright wrote:
>>> On 10/10/2014 3:06 PM, Timon Gehr wrote:
>>>> On 10/10/2014 11:25 PM, Walter Bright wrote:
>>>>>
>>>>> Essentially, the rules for multiple alias this should be the same as for
>>>>> multiple imports and multiple mixin templates. These rules work, and the
>>>>> consistency will be expected.
>>>>
>>>> Agreed. Do you suggest to overload alias this against imports and
>>>> mixin templates?
>>>
>>> I hadn't thought of that (thanks for bringing it up). My first thought
>>> is no. Alias this gets searched after those do, because it comes into
>>> play only when the symbol isn't resolved in the scope.
>>
>> This allows for symbol hijacking (this is also the current behaviour):
>>
>> // ---
>>
>> module m;
>> import std.stdio;
>> // void foo(int x){ writeln("hi from m"); } // uncomment to hijack
>>
>> // ---
>>
>> module main;
>> import std.stdio;
>>
>> struct T{
>>     import m;
>>     alias s this;
>>     S s;
>> }
>>
>>
>> struct S{
>>     void foo(int x){ writeln("hi from S"); }
>> }
>>
>> void main(){
>>     T t;
>>     t.foo(1);
>> }
>
> Hmm. Good point. The alias this should be done before imports.

Symmetrically. You may use symbol from import, uncomment it in aliased type and hijack it.
October 10, 2014
BTW.

Overloaded functions in PR resolves un-properly (raises error even if can be resolved correct function)
However it's easy to fix and I'll do it tomorrow.
October 11, 2014
On 10/10/2014 4:23 PM, IgorStepanov wrote:
> On Friday, 10 October 2014 at 22:50:25 UTC, Walter Bright wrote:
>> must be an error, even if one of C.a() or C.b() might be a "better" match.
>> This is how things work for template mixins and imports.
> So it is.

Good!

The same rule applies for overloading.
October 11, 2014
On 2014-10-11 00:52, Walter Bright wrote:

> I like the C++ rule that says that access control is not considered for
> name lookup. I know it makes for some annoying results, but the
> simplicity of the rule makes it much more understandable.

I'm not so sure about that. Perhaps it makes it more understandable for a language designer. But not for a user. You try to call a function but you get a conflict with a private symbol. The user will get frustrated thinking: "stupid compiler, of course I want to call the public function".

-- 
/Jacob Carlborg
October 11, 2014
On Saturday, 11 October 2014 at 00:00:48 UTC, Walter Bright wrote:
> On 10/10/2014 4:23 PM, IgorStepanov wrote:
>> On Friday, 10 October 2014 at 22:50:25 UTC, Walter Bright wrote:
>>> must be an error, even if one of C.a() or C.b() might be a "better" match.
>>> This is how things work for template mixins and imports.
>> So it is.
>
> Good!
>
> The same rule applies for overloading.

I've implemented overloading:
https://github.com/D-Programming-Language/dmd/pull/3998/files#diff-17b22eae29e74ce6ec29037438b5031cR2136

Please, tell me, what changes should I make to the DIP as a result of yesterday's discussions.
And please, tell your opinion about "is" issue:

class A
{
   int i;
   alias i this;
}

class B
{
   int i;
   alias i this;
}

class C
{
   A a;
   B b;
   alias a this;
   alias b this;
}

void foo(T)(T arg) if(is(T : int))
{
   ...
}

foo(C()); //Should it pass or not?
October 12, 2014
On 10/11/2014 3:42 AM, Jacob Carlborg wrote:
> On 2014-10-11 00:52, Walter Bright wrote:
>
>> I like the C++ rule that says that access control is not considered for
>> name lookup. I know it makes for some annoying results, but the
>> simplicity of the rule makes it much more understandable.
>
> I'm not so sure about that. Perhaps it makes it more understandable for a
> language designer. But not for a user. You try to call a function but you get a
> conflict with a private symbol. The user will get frustrated thinking: "stupid
> compiler, of course I want to call the public function".

The theory is that simpler rules are better than complex rules, even if the simpler rules aren't always ideal.

October 12, 2014
On 10/11/2014 7:23 AM, IgorStepanov wrote:
> On Saturday, 11 October 2014 at 00:00:48 UTC, Walter Bright wrote:
>> On 10/10/2014 4:23 PM, IgorStepanov wrote:
>>> On Friday, 10 October 2014 at 22:50:25 UTC, Walter Bright wrote:
>>>> must be an error, even if one of C.a() or C.b() might be a "better" match.
>>>> This is how things work for template mixins and imports.
>>> So it is.
>>
>> Good!
>>
>> The same rule applies for overloading.
>
> I've implemented overloading:
> https://github.com/D-Programming-Language/dmd/pull/3998/files#diff-17b22eae29e74ce6ec29037438b5031cR2136
>
>
> Please, tell me, what changes should I make to the DIP as a result of
> yesterday's discussions.

At the very least, it should say it resolves ambiguities the same way that imports and template mixins do.


> And please, tell your opinion about "is" issue:
>
> class A
> {
>     int i;
>     alias i this;
> }
>
> class B
> {
>     int i;
>     alias i this;
> }
>
> class C
> {
>     A a;
>     B b;
>     alias a this;
>     alias b this;
> }
>
> void foo(T)(T arg) if(is(T : int))
> {
>     ...
> }
>
> foo(C()); //Should it pass or not?

There's a rule with imports that if the same symbol is reachable via multiple paths through the imports, that it is not an ambiguity error. Here, the same type is reachable through multiple alias this paths, so by analogy it shouldn't be an error.
October 12, 2014
On Sunday, 12 October 2014 at 04:31:22 UTC, Walter Bright wrote:
> On 10/11/2014 7:23 AM, IgorStepanov wrote:
>> class A
>> {
>>    int i;
>>    alias i this;
>> }
>>
>> class B
>> {
>>    int i;
>>    alias i this;
>> }
>>
>> class C
>> {
>>    A a;
>>    B b;
>>    alias a this;
>>    alias b this;
>> }
>>
>> void foo(T)(T arg) if(is(T : int))
>> {
>>    ...
>> }
>>
>> foo(C()); //Should it pass or not?
>
> There's a rule with imports that if the same symbol is reachable via multiple paths through the imports, that it is not an ambiguity error. Here, the same type is reachable through multiple alias this paths, so by analogy it shouldn't be an error.

It's the same type, but different symbols; actual accesses would be ambiguous. `is(T : int)` shouldn't evaluate to true if `int a = T.init;` would fail.
October 12, 2014
On 11/10/14 00:52, Walter Bright via Digitalmars-d wrote:
> I like the C++ rule that says that access control is not considered for name
> lookup. I know it makes for some annoying results, but the simplicity of the
> rule makes it much more understandable.

That's fine.  I just wanted to be sure that there wasn't a risk of multiple alias this breaking in unpleasant ways, if/when https://issues.dlang.org/show_bug.cgi?id=10996 is fixed.