On 12/23/2014 10:42 AM, IgorStepanov wrote:
On Saturday, 20 December 2014 at 21:25:28 UTC, Andrei Alexandrescu wrote:
On 11/2/14 6:57 AM, IgorStepanov wrote:
And there is dispute about is expression: see
http://forum.dlang.org/thread/ubafmwvxwtolhmnxb...@forum.dlang.org?page=5

OK, time to get this approved.

First, the current DIP doesn't seem to address this:

Walter and I would agree to making the presence of BOTH alias this
and opDispatch a compile-time error. That would break existing code
but not change semantics silently.

Far as I remember it was left to the discussion. Nobody objected to this issue,
thus we may accept it. I think.

Ok, let's make it an error.


Any thoughts on this? Currently opDispatch gets priority over alias this, see
lookup step 3 in section "Semantics" of http://wiki.dlang.org/DIP66. That's
problematic because it puts opDispatch in _between_ "normal" subtyping via
inheritance and alias this, which is supposed to be just as solid as 
inheritance.

I think the principled solution is to combine steps 2 and 4 into step 2, i.e.
alias this is as strong as inheritance. Any ambiguous symbols would be rejected.

The second possibility, less principled but probably practical, would be to
swap steps 3 and 4. That way alias this has juuust a teensy bit a lower status
than regular inheritance.

It looks nice, but it can greatly break the existing code. I suggest a postpone
this issue and discuss the semantic order in a separate discusson/
The simplest thing (which Walter favors) is to make the presence of both
opDispatch and alias this a compile-time error. That would break only a teensy
amount of code if any, and would give us time to investigate the best approach
when compelling use cases come about. So I suggest we move forward with that
for this DIP.

Regarding the is-expression controversy in
http://forum.dlang.org/thread/ubafmwvxwtolhmnxb...@forum.dlang.org?page=5:

First off, is(S : T) is a subtyping test - is S a non-proper subtype of T, or
not? (Non-proper or improper subtyping: S is allowed to be identical to T).
"alias this" is a mechanism that introduces subtyping. It follows that
subtyping introduced via "alias this" must be detected with is-expressions.

Now, you give an example of subtyping where one or more two objects of the
same supertype may be reached through two or more different paths. This is a
well-known problem in subtyping (known as diamond hierarchy or repeated
inheritance).

In the case of "alias this", different objects of the same type may be
reachable (or at least the compiler is unable to tell statically whether the
objects are distinct or not). A correct but hamfisted solution would be to
sever the subtyping relationship whenever the same type is reachable through
multiple paths.

The versatility of "alias this", however, suggests a better solution: if T is
indirectly reachable as a supertype of S through more than one path and the
subtyping is either tested (by means of an is-expression) or effected (by
means of an implicit conversion), the compiler should issue a compile-time
error asking the user to define an "alias this" DIRECTLY inside S, which takes
precedence over indirect reachability and informs the type system which T of
the several reachable ones is needed.

Please let me know of any thoughts. Thanks!

Summing up.
There are three way to process is(D: B) where D may be converted to B in several
ways.
1. is(D: B) should return false: D is not subtype of B now.
2. is(D: B) should return true: D is subtype of B anyway.
3. is(D: B) should raise an error: let the user decide what he wants.

I strongly aganist the first way. It means that is(D: B) may absorb the real
error, if it happens.
Now only two construction in D may absorb errors:
is(typeof(something)) and __traits(compiles, anything)).
I say "absorb" when compiler see the error, ignores it and changes way of
compilation:
static if (<noErrors>)
     <correct branch>
else
     <error branch>

This situation may cause strage errors, code hijacking and other bad things,
thus user should has a possibility to keep track of such cases.
is(typeof(something)) and __traits(compiles, anything)) is a special
constructions to error handling and user and everyone understands what is 
expected.
is(D: B) is trusted construction and it can't create problems now. Let's leave
it so.

The second way is better, I think. It doesn't absorb the error, it skip error
but doesn't change the compilation way.
Error will be raised anyway when compiler will process code which use this 
casting.
void foo(D)(D obj) if (is(D: Base)) // compiler will skip the error here...
{
     Base b = obj; //... but it will raise the error here.
}

The third way is correct too, I think. It raises error earlier, but I changes
current `is` semantic. AFAIK, `is` doesn't raise errors now.

The current behavior of:

    is (D : B)

is the expression will evaluate to false if D does not compile. However, a compile time error will be issued if B does not compile.

If D and B compile, then it will evaluate to false if B is not implicitly convertible to D. This suggests to me Option 1, i.e. if the implicit conversion fails due to ambiguity errors, then it should return false (not issue a compile time error).

I'm not sure what you mean by "absorb the real error".


the compiler should issue
a compile-time error asking the user to define an "alias this" DIRECTLY
inside S, which takes precedence over indirect reachability and informs
the type system which T of the several reachable ones is needed.

That means that user should may override inherited alias this declarations:

struct A
{
     alias i this;
     int i;
}

struct B
{
     alias i this;
     int i;
}

struct C
{
     alias a this;
     alias b this;
     alias b.i this; //override inherited alias int this.
     A a;
     B b;
}

It was implemented in my first implementation, but AFAIR you suggested delay it
for postpone this feature and introduce it later. Thus now I remove this option
from PR and DIP, but I may revert it back.

P.S. sorry for big latency, it will take place within a couple of months, but I
will do this work anyway.

Reply via email to