Re: DIP66 v1.1 (Multiple) alias this.

2016-06-26 Thread mogu via Digitalmars-d

On Monday, 27 June 2016 at 00:13:46 UTC, mogu wrote:

On Friday, 8 May 2015 at 13:57:56 UTC, Andrea Fontana wrote:
Is "multiple alias this" implementation planned in near 
future? It could be useful for a project of mine :)


I need it too, and also do static inheritance.
http://wiki.dlang.org/DIP84


I implemented a limited version of multiple alias this:
https://github.com/mogud/MultiAliasThis/blob/master/mat.d

But it's only useful in composition. Static polymorphism(by 
implicit conversion in alias this) cannot work.


Re: DIP66 v1.1 (Multiple) alias this.

2016-06-26 Thread mogu via Digitalmars-d

On Friday, 8 May 2015 at 13:57:56 UTC, Andrea Fontana wrote:
On Saturday, 27 December 2014 at 12:28:34 UTC, Joseph Rushton 
Wakeling wrote:

On 26/12/14 19:53, Daniel N via Digitalmars-d wrote:
Anyway considering the new ways of working, when using the 
-dip switch for the
initial few releases, there is ample time to perfect all 
details.


Potentially related issue, regarding implicit conversion.  
Given a struct as follows:


struct Integer
{
int i_;

alias i_ this;
}

Can anyone explain to me why this works:

Integer i = Integer(3);
i = 5;

... but this doesn't:

Integer i = 5;

It seems unintuitive, in the circumstances.


Is "multiple alias this" implementation planned in near future? 
It could be useful for a project of mine :)


I need it too, and also do static inheritance.
http://wiki.dlang.org/DIP84


Re: DIP66 v1.1 (Multiple) alias this.

2015-05-08 Thread Andrea Fontana via Digitalmars-d
On Saturday, 27 December 2014 at 12:28:34 UTC, Joseph Rushton 
Wakeling wrote:

On 26/12/14 19:53, Daniel N via Digitalmars-d wrote:
Anyway considering the new ways of working, when using the 
-dip switch for the
initial few releases, there is ample time to perfect all 
details.


Potentially related issue, regarding implicit conversion.  
Given a struct as follows:


struct Integer
{
int i_;

alias i_ this;
}

Can anyone explain to me why this works:

Integer i = Integer(3);
i = 5;

... but this doesn't:

Integer i = 5;

It seems unintuitive, in the circumstances.


Is "multiple alias this" implementation planned in near future? 
It could be useful for a project of mine :)




Re: DIP66 v1.1 (Multiple) alias this.

2014-12-27 Thread Joseph Rushton Wakeling via Digitalmars-d

On 26/12/14 19:53, Daniel N via Digitalmars-d wrote:

Anyway considering the new ways of working, when using the -dip switch for the
initial few releases, there is ample time to perfect all details.


Potentially related issue, regarding implicit conversion.  Given a struct as 
follows:


struct Integer
{
int i_;

alias i_ this;
}

Can anyone explain to me why this works:

Integer i = Integer(3);
i = 5;

... but this doesn't:

Integer i = 5;

It seems unintuitive, in the circumstances.


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-26 Thread Andrei Alexandrescu via Digitalmars-d

On 12/26/14 12:37 PM, Walter Bright wrote:

On 12/23/2014 10:17 PM, Andrei Alexandrescu wrote:

In fact a better thought: as soon as D is defined, repeated subtyping
should be
detected as an error. Then there's no question about "is" in the first
place :o).


That's a good idea, but I think it is unworkable. What is the set of
types that B is implicitly convertible too? It's unbounded.


I think it's bounded. Example to the contrary? -- Andrei




Re: DIP66 v1.1 (Multiple) alias this.

2014-12-26 Thread Walter Bright via Digitalmars-d

On 12/23/2014 10:17 PM, Andrei Alexandrescu wrote:

On 12/23/14 8:54 PM, Walter Bright wrote:


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).


Though I agree it makes sense to just return false, I think it would be more
sensible and useful to issue an error. If B is reachable from B through multiple
paths, that's a new situation distinct from yes/no.


That would be inconsistent with how 'is' works for other types.



In fact a better thought: as soon as D is defined, repeated subtyping should be
detected as an error. Then there's no question about "is" in the first place 
:o).


That's a good idea, but I think it is unworkable. What is the set of types that 
B is implicitly convertible too? It's unbounded.




Re: DIP66 v1.1 (Multiple) alias this.

2014-12-26 Thread Daniel N via Digitalmars-d
On Wednesday, 24 December 2014 at 22:09:49 UTC, Andrei 
Alexandrescu wrote:
Is there a need for explicit overriding, i.e. any inadvertent 
error people may make without it? -- Andrei


I failed to find any dangerous refactoring sequences, so it might 
be superfluous, however I found another minor issue, see below.


Anyway considering the new ways of working, when using the -dip 
switch for the initial few releases, there is ample time to 
perfect all details.


// Example 1
struct A {int i;alias i this;}
struct Z
{
  A a;
  alias a   this;
}

// A is preferred since it requires only one implicit conversion.
void process(A)   {}
void process(int) {}

// Example 2
struct A {int i;alias i this;}
struct B {int i;alias i this;}
struct Z
{
  A a;
  B b;
  alias a   this;
  alias b   this;
  alias a.i this;
}

// The below is now ambiguous because Z is directly convertible 
to 'int' although we only intended to disambiguate between 
Z->A->int and Z->B->int

void process(A)   {}
void process(int) {}



Re: DIP66 v1.1 (Multiple) alias this.

2014-12-24 Thread Andrei Alexandrescu via Digitalmars-d

On 12/24/14 12:58 AM, Daniel Nielsen wrote:

On Wednesday, 24 December 2014 at 06:17:28 UTC, Andrei Alexandrescu wrote:

In fact a better thought: as soon as D is defined, repeated subtyping
should be detected as an error. Then there's no question about "is" in
the first place :o).


Andrei


Agreed. How about using "override alias this" when disambiguating, in
order to make it more explicit?

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


Is there a need for explicit overriding, i.e. any inadvertent error 
people may make without it? -- Andrei


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-24 Thread Daniel Nielsen via Digitalmars-d
On Wednesday, 24 December 2014 at 06:17:28 UTC, Andrei 
Alexandrescu wrote:
In fact a better thought: as soon as D is defined, repeated 
subtyping should be detected as an error. Then there's no 
question about "is" in the first place :o).



Andrei


Agreed. How about using "override alias this" when 
disambiguating, in order to make it more explicit?


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


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-23 Thread Andrei Alexandrescu via Digitalmars-d

On 12/23/14 8:54 PM, Walter Bright wrote:


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).


Though I agree it makes sense to just return false, I think it would be 
more sensible and useful to issue an error. If B is reachable from B 
through multiple paths, that's a new situation distinct from yes/no.


In fact a better thought: as soon as D is defined, repeated subtyping 
should be detected as an error. Then there's no question about "is" in 
the first place :o).



Andrei



Re: DIP66 v1.1 (Multiple) alias this.

2014-12-23 Thread Walter Bright via Digitalmars-d

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 ()
 
else
 

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

Re: DIP66 v1.1 (Multiple) alias this.

2014-12-23 Thread IgorStepanov via Digitalmars-d
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.


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 ()

else


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 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 

Re: DIP66 v1.1 (Multiple) alias this.

2014-12-22 Thread Joseph Rushton Wakeling via Digitalmars-d

On 21/12/14 09:23, deadalnix via Digitalmars-d wrote:

I have nothing against this, but this is, indeed, completely out of the scope
(!) of the DIP.


Fair enough.  I wanted to make sure there was nothing here that could interact 
nastily with protection attributes.




Re: DIP66 v1.1 (Multiple) alias this.

2014-12-22 Thread Joseph Rushton Wakeling via Digitalmars-d

On 21/12/14 11:11, Dicebot via Digitalmars-d wrote:

On Sunday, 21 December 2014 at 08:23:34 UTC, deadalnix wrote:

See also: https://issues.dlang.org/show_bug.cgi?id=10996


I have nothing against this, but this is, indeed, completely out of the scope
(!) of the DIP.


I think it belongs to DIP22


In fact it's already in there:

A public alias to a private symbol makes the symbol
accessibly through the alias. The alias itself needs
to be in the same module, so this doesn't impair
protection control.

It's just not implemented for alias this.


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-21 Thread Dicebot via Digitalmars-d

On Sunday, 21 December 2014 at 08:23:34 UTC, deadalnix wrote:

See also: https://issues.dlang.org/show_bug.cgi?id=10996


I have nothing against this, but this is, indeed, completely 
out of the scope (!) of the DIP.


I think it belongs to DIP22


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-21 Thread deadalnix via Digitalmars-d
On Saturday, 20 December 2014 at 23:22:40 UTC, Joseph Rushton 
Wakeling via Digitalmars-d wrote:

On 02/11/14 15:55, IgorStepanov via Digitalmars-d wrote:

http://wiki.dlang.org/DIP66

I've applied some changes to it, however there are still some 
unresolved questions.


The current DIP doesn't address protection attributes.  I 
recognize this might be somewhat orthogonal, but it'd be nice 
to build it into the DIP if possible, just to be explicit about 
what is expected for how alias this should work.


According to TDPL the following should work:

struct Foo
{
private T internal_; // member variable is 
private


public alias internal_ this; // .. but can be 
interacted with

 // via the public alias
}

It seems to me an important factor, because it means that 
classes and structs can use subtyping without revealing the 
implementation details.  As things are, you wind up having to 
do something like,


struct Integer
{
private int i_;

public ref int getInteger() @property
{
return i_;
}

alias getInteger this;
}

... which personally I find a bit of an unpleasant violation of 
the idea of a private implementation.


See also: https://issues.dlang.org/show_bug.cgi?id=10996


I have nothing against this, but this is, indeed, completely out 
of the scope (!) of the DIP.


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-20 Thread Joseph Rushton Wakeling via Digitalmars-d

On 02/11/14 15:55, IgorStepanov via Digitalmars-d wrote:

http://wiki.dlang.org/DIP66

I've applied some changes to it, however there are still some unresolved 
questions.


The current DIP doesn't address protection attributes.  I recognize this might 
be somewhat orthogonal, but it'd be nice to build it into the DIP if possible, 
just to be explicit about what is expected for how alias this should work.


According to TDPL the following should work:

struct Foo
{
private T internal_; // member variable is private

public alias internal_ this; // .. but can be interacted with
 // via the public alias
}

It seems to me an important factor, because it means that classes and structs 
can use subtyping without revealing the implementation details.  As things are, 
you wind up having to do something like,


struct Integer
{
private int i_;

public ref int getInteger() @property
{
return i_;
}

alias getInteger this;
}

... which personally I find a bit of an unpleasant violation of the idea of a 
private implementation.


See also: https://issues.dlang.org/show_bug.cgi?id=10996


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-20 Thread Andrei Alexandrescu via Digitalmars-d

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.


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.


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!


Andrei


Re: DIP66 v1.1 (Multiple) alias this.

2014-12-05 Thread IgorStepanov via Digitalmars-d


Bump


Re: DIP66 v1.1 (Multiple) alias this.

2014-11-03 Thread IgorStepanov via Digitalmars-d

On Monday, 3 November 2014 at 20:06:27 UTC, Marc Schütz wrote:

On Monday, 3 November 2014 at 15:39:42 UTC, IgorStepanov wrote:
I meant that when you say that X is a subtype of T and X is a 
subtype of V where you don't know what T and V are, it means 
you don't really know what you're doing. And that is an error 
and the compiler should inform you about it as soon as 
possible. However I may be mistaken.


IMO the behaviour should be analogous to name lookup for 
modules: there should be an error only on use. It's hard to 
come up with a non-artificial example, but I can imagine there 
are some valid use cases in generic code. It won't hurt to 
report the ambiguity error on use, while it could theoretically 
hurt to report it early, so I'd suggest to go with the former.


There are two cases:
1: when "alias a this" tries to override base class typeof(a)
2: when "alias a this" tries to override "alias b this" where 
"is(typeof(a) == typeof(b))"


The first check is hard to implement at lookup-time, because base 
classes are resolved before alias this.
The second check may be easely dropped (anyway alias this 
conflicts are resolved properly at lookup time).


Do you accept this scheme (remove the second check but still 
alive the first check)?


Re: DIP66 v1.1 (Multiple) alias this.

2014-11-03 Thread via Digitalmars-d

On Monday, 3 November 2014 at 15:39:42 UTC, IgorStepanov wrote:
I meant that when you say that X is a subtype of T and X is a 
subtype of V where you don't know what T and V are, it means 
you don't really know what you're doing. And that is an error 
and the compiler should inform you about it as soon as 
possible. However I may be mistaken.


IMO the behaviour should be analogous to name lookup for modules: 
there should be an error only on use. It's hard to come up with a 
non-artificial example, but I can imagine there are some valid 
use cases in generic code. It won't hurt to report the ambiguity 
error on use, while it could theoretically hurt to report it 
early, so I'd suggest to go with the former.


Re: DIP66 v1.1 (Multiple) alias this.

2014-11-03 Thread IgorStepanov via Digitalmars-d
* "At the AliasThis declaration semantic stage, the compiler 
can

perform the initial checks and reject the obviously incorrect
AliasThis declarations." -> it might be simpler (for the sake 
of
simplifying generic code) to just delay all error checking to 
the

first use.


I disagree with that. Current check is not recursive and 
prevent you

code from a silly errors:

struct X(T, V)
{
   T t;
   V v;
   alias t this;
   alias v this; //Error if is(T == V). However this code is
fundamentally broken, and this error should be raised as soon 
as possible.

}


The code is not fundamentally broken if alias this is never 
used. I agree rejecting the code compulsively is also sensible, 
ONLY if there is a simple way to write a static if condition to 
make the code work. Meaning:


struct X(T, V)
{
T t;
V v;
static if (please_fill_this)
alias t this;
static if (please_fill_this_too)
alias v this;
}

If the two conditions are too hard to write then it would be 
difficult to argue this point successfully.


This code can be rewritten as:

struct X(T, V)
{
T t;
V v;
alias t this;
static if (!is(V == T))
alias v this;
}


The code is not fundamentally broken if alias this is never
used.


I meant that when you say that X is a subtype of T and X is a 
subtype of V where you don't know what T and V are, it means you 
don't really know what you're doing. And that is an error and the 
compiler should inform you about it as soon as possible. However 
I may be mistaken.


Understood. All: okay to make alias this + opDispach applicable 
to the

same expression an error?

I think it will be nice.

I'm sending this now with these points, will make one more pass 
through

the DIP when I'm online again.

Ok, I'll wait.

And please, answer the question about the is-expression.


Re: DIP66 v1.1 (Multiple) alias this.

2014-11-03 Thread Andrei Alexandrescu via Digitalmars-d

On 11/2/14 6:55 AM, IgorStepanov wrote:

http://wiki.dlang.org/DIP66


* "At the AliasThis declaration semantic stage, the compiler can
perform the initial checks and reject the obviously incorrect
AliasThis declarations." -> it might be simpler (for the sake of
simplifying generic code) to just delay all error checking to the
first use.


I disagree with that. Current check is not recursive and prevent you
code from a silly errors:

struct X(T, V)
{
T t;
V v;
alias t this;
alias v this; //Error if is(T == V). However this code is
fundamentally broken, and this error should be raised as soon as possible.
}


The code is not fundamentally broken if alias this is never used. I 
agree rejecting the code compulsively is also sensible, ONLY if there is 
a simple way to write a static if condition to make the code work. Meaning:


struct X(T, V)
{
T t;
V v;
static if (please_fill_this)
alias t this;
static if (please_fill_this_too)
alias v this;
}

If the two conditions are too hard to write then it would be difficult 
to argue this point successfully.



class A : B
{
B b;
alias b this; //Error: super type (B) always hides "aliasthised"
type B because base classes should be processed before alias this types.
}


That's fine to reject in all cases.


* Regarding the lookup, opDispatch shouldn't come before alias this,
or should come before base class lookup. Essentially alias this is
subtyping so it should enjoy similar privileges to base classes. A
different way to look at it is opDispatch is a "last resort" lookup
mechanism, just one step above the UFCS lowering.


I agree with this suggestion, however it breaks an existing code.


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.


When alias this was introduced the decision of opDispatch vs. alias this 
was not deeply elaborated. In hindsight opDispatch should probably have 
come after because it's really a "method not found" catch-all whereas 
alias this is subtyping. That said, compelling arguments might come 
later the other direction. So making it an error for now would be 
sensible. It should only affect rather obscure code.



opDispatch shouldn't come before base type lookup, because it will hide
basic methods like toString.


Agreed.


opDispatch may come after alias this lookup, however it will
fundamentally change program behaviour.


Understood.


Current (implemented is released compiler) behaviour:

[snip]

Understood. All: okay to make alias this + opDispach applicable to the 
same expression an error?



And, TBH, this issue not relevant with multiple alias this :-)


Agreed. It is, however, good to revisit the decision and tighten that 
screw properly now that we have the opportunity.



* The DIP should specify the working of alias this as
rewrites/lowerings, not pseudocode. Basically for each kth declaration
"alias symbolk this;" the compiler rewrites "obj.xyz" as
"obj.symbolk.xyz" and then does the usual lookup on that expression.
That means the whole algorithms is applied again etc. If more than one
rewrite typechecks, that's an ambiguity error.


Ok. I've removed pseudocode. Is it better now?


I'm flying now :o)... will take a look.


* IMPORTANT: The DIP must discuss rvalue vs. lvalue cases.


Done. I've added corresponding chapter to the DIP and commit to the PR.


I'm sending this now with these points, will make one more pass through 
the DIP when I'm online again.



Andrei



Re: DIP66 v1.1 (Multiple) alias this.

2014-11-02 Thread Sativa via Digitalmars-d

class A : B
{
   B b;
   alias b this; //Error: super type (B) always hides 
"aliasthised" type B because base classes should be processed 
before alias this types.

}



This isn't an error? Just because A inherits B doesn't mean that 
the alias is wrong?


e.g., If you have

class A1 { B b; alias b this; }

and

class A2 : B { B b; alias b this; }

A2 is just A1 in all forms. Whats great about it is that it 
allows easy composition patterns. (that is, A1 has essentially 
implemented B through the alias)


e.g., we can reassign b to a different behavior without having to 
write any boil code. It allows one to decompose classes and their 
implementations in a natural way.


Of course, it would require the alias this to be processed before 
the base class.


I think that it would be worth the alias to override the 
inheritance because it makes things easier:



class A : BBB { BB b; alias b this; }

If BBB and BB are related in some complex way the compiler has to 
deduce this. e.g.,


class BBB : Q!B { }

where Q!B is some template that is a superclass of B.

But if the alias is processed first, it won't matter.


* Regarding the lookup, opDispatch shouldn't come before alias 
this, or should come before base class lookup. Essentially 
alias this is subtyping so it should enjoy similar privileges 
to base classes. A different way to look at it is opDispatch 
is a "last resort" lookup mechanism, just one step above the 
UFCS lowering.


I agree with this suggestion, however it breaks an existing 
code.
opDispatch shouldn't come before base type lookup, because it 
will hide basic methods like toString.
opDispatch may come after alias this lookup, however it will 
fundamentally change program behaviour.


Why can't you simply have opDispatch call the base class lookup 
if all others fail?


It seems to me that one should have

alias this > opDispatch > class > base class(es)

But each one has a fall through mechanism.

e.g., if someone overrides toString in opDispatch it will call 
their function, if not, it gets passed to the bass class tostring.


Why should it work this way? Because alias this and opDispatch 
are user defined. The user "knows" why they are doing and the 
compiler doesn't get in the way by preventing them from doing 
things they want to do.


The compiler essentially fixes up all the missing connections 
that it can but never forcing connections the user may not want.



Basically all one needs is something like

bool opAliasDispatch(...)
{
   if (...) { ... return true; } // tries to dispatch
   return false;
}


bool opDispatch(...)
{
   if (...) { ... return true; } // tries to dispatch
   return false;
}

bool opClassDispatch(...)
{
   if (...) { ... return true; } // tries to dispatch
   return false;
}

bool opBaseDispatch(...)
{
   if (...) { ... return true; } // tries to dispatch
   return false;
}

Then a master dispatcher is

bool opMasterDispatch(...)
{
   return opAliasDispatch(...) || opDispatch(...) || 
opClassDispatch(...) || opBaseDispatch(...);

}



This makes it easier to add new dispatchers in the future, etc.

Also, if you are worried about backwards compatibility, just 
create a command line switch to select one method over another. 
Easy and it doesn't force everyone to be stuck with a suboptimal 
solution just for "backwards compatibility"(which is the scourge 
of humanity... We have to move forward, not be stuck in the 
past!!!).




Re: DIP66 v1.1 (Multiple) alias this.

2014-11-02 Thread IgorStepanov via Digitalmars-d
And there is dispute about is expression: see 
http://forum.dlang.org/thread/ubafmwvxwtolhmnxb...@forum.dlang.org?page=5


DIP66 v1.1 (Multiple) alias this.

2014-11-02 Thread IgorStepanov via Digitalmars-d

http://wiki.dlang.org/DIP66

I've applied some changes to it, however there are still some 
unresolved questions.



Here's my destruction:

* "symbol can be a field or a get-property (method annotated 
with @property and taking zero parameters)." -> actually:


(a) the @property annotation is not necessary
(b) there may be one ore more parameters so long as they're all 
defaulted


So the text should be "obj.symbol must be a valid expression".


Done.

* "At the AliasThis declaration semantic stage, the compiler 
can perform the initial checks and reject the obviously 
incorrect AliasThis declarations." -> it might be simpler (for 
the sake of simplifying generic code) to just delay all error 
checking to the first use.


I disagree with that. Current check is not recursive and prevent 
you code from a silly errors:


struct X(T, V)
{
   T t;
   V v;
   alias t this;
   alias v this; //Error if is(T == V). However this code is 
fundamentally broken, and this error should be raised as soon as 
possible.

}

class A : B
{
   B b;
   alias b this; //Error: super type (B) always hides 
"aliasthised" type B because base classes should be processed 
before alias this types.

}

* I don't think the pseudocode helps a lot. Better let's have a 
clear and precise specification (I've edited the lookup order 
into an ordered list).


Done.

* Regarding the lookup, opDispatch shouldn't come before alias 
this, or should come before base class lookup. Essentially 
alias this is subtyping so it should enjoy similar privileges 
to base classes. A different way to look at it is opDispatch is 
a "last resort" lookup mechanism, just one step above the UFCS 
lowering.


I agree with this suggestion, however it breaks an existing code.
opDispatch shouldn't come before base type lookup, because it 
will hide basic methods like toString.
opDispatch may come after alias this lookup, however it will 
fundamentally change program behaviour.


Current (implemented is released compiler) behaviour:
import std.stdio;

struct Base
{
string foo()
{
return "Base.foo";
}
}

struct Derived
{
Base b;
alias b this;

string opDispatch(string s)()
{
return "opDispatch";
}
}

void main()
{
Derived d;
writeln(d.foo()); //prints "opDispatch"
}

After your change this call will write "Base.foo". And I see no 
way to add third "transitional" state to allow users rewrite 
those code correctly.
This changing will suddenly, without any warning, change a user 
code. I understand that this case is very rare however it may be.


And, TBH, this issue not relevant with multiple alias this :-)


* The DIP should specify the working of alias this as 
rewrites/lowerings, not pseudocode. Basically for each kth 
declaration "alias symbolk this;" the compiler rewrites 
"obj.xyz" as "obj.symbolk.xyz" and then does the usual lookup 
on that expression. That means the whole algorithms is applied 
again etc. If more than one rewrite typechecks, that's an 
ambiguity error.


Ok. I've removed pseudocode. Is it better now?

* IMPORTANT: The DIP must discuss rvalue vs. lvalue cases. The 
rewrite approach simplifies that discussion because it's clear 
what happens by simply reasoning about the rewritten 
expression. Lvalue vs. rvalue matters a lot practically. 
Consider:


struct A
{
private int x;
alias x this;
}

struct B
{
private int _x;
int x() { return x; }
alias x this;
}

Then x can be passed by reference, modified directly etc. for A 
but not for B.


Done. I've added corresponding chapter to the DIP and commit to 
the PR.