www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - override(T)

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter and I discussed last night about contravariance and all and could 
not find a compelling argument in favor of implementing contravariant 
arguments right now. The feature is nontrivial to implement, potentially 
surprising, and has a number of odd corner cases.

One feature that does get requested often in C++ and Java is the ability 
to choose which class/interface contains the method you want to 
override. Consider:

interface Lottery {  void draw();  }
interface Figure {  void draw();  }

class LotterySimulation : Lottery, Figure {
     override void draw();
}

Right now draw() overrides both methods, but you'd want to override them 
separately. You could do so through an intermediate interface:

class Figure2 : Figure {  void draw2() { return draw(); }  }
class LotterySimulation : Lottery, Figure2 {
     override void draw();
     override void draw2();
}

There are a few problems with this, among which the fact that 
LotterySimulation now cannot inherit another class; the one class slot 
was occupied by Figure2.

So I was thinking of this:

class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
}

This is easy to implement, scales well, and has good real world uses. 
What say you?


Andrei
Sep 24 2009
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Walter and I discussed last night about contravariance and all and could  
 not find a compelling argument in favor of implementing contravariant  
 arguments right now. The feature is nontrivial to implement, potentially  
 surprising, and has a number of odd corner cases.

 One feature that does get requested often in C++ and Java is the ability  
 to choose which class/interface contains the method you want to  
 override. Consider:

 interface Lottery {  void draw();  }
 interface Figure {  void draw();  }

 class LotterySimulation : Lottery, Figure {
      override void draw();
 }

 Right now draw() overrides both methods, but you'd want to override them  
 separately. You could do so through an intermediate interface:

 class Figure2 : Figure {  void draw2() { return draw(); }  }
 class LotterySimulation : Lottery, Figure2 {
      override void draw();
      override void draw2();
 }

 There are a few problems with this, among which the fact that  
 LotterySimulation now cannot inherit another class; the one class slot  
 was occupied by Figure2.

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses.  
 What say you?

In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2? In the override(T) world, What does this do? auto ls = new LotterySimulation(); ls.draw(); ??? I'm not sure this works... -Steve
Sep 24 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Walter and I discussed last night about contravariance and all and 
 could not find a compelling argument in favor of implementing 
 contravariant arguments right now. The feature is nontrivial to 
 implement, potentially surprising, and has a number of odd corner cases.

 One feature that does get requested often in C++ and Java is the 
 ability to choose which class/interface contains the method you want 
 to override. Consider:

 interface Lottery {  void draw();  }
 interface Figure {  void draw();  }

 class LotterySimulation : Lottery, Figure {
      override void draw();
 }

 Right now draw() overrides both methods, but you'd want to override 
 them separately. You could do so through an intermediate interface:

 class Figure2 : Figure {  void draw2() { return draw(); }  }
 class LotterySimulation : Lottery, Figure2 {
      override void draw();
      override void draw2();
 }

 There are a few problems with this, among which the fact that 
 LotterySimulation now cannot inherit another class; the one class slot 
 was occupied by Figure2.

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses. 
 What say you?

In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2? In the override(T) world, What does this do? auto ls = new LotterySimulation(); ls.draw(); ??? I'm not sure this works... -Steve

That would be a compile-time error. You'd need to extract the interface you want to work with, and then call against it. In addition, LotterySimulation could offer convenience functions that do that. Andrei
Sep 24 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Walter and I discussed last night about contravariance and all and 
 could not find a compelling argument in favor of implementing 
 contravariant arguments right now. The feature is nontrivial to 
 implement, potentially surprising, and has a number of odd corner cases.

 One feature that does get requested often in C++ and Java is the 
 ability to choose which class/interface contains the method you want 
 to override. Consider:

 interface Lottery {  void draw();  }
 interface Figure {  void draw();  }

 class LotterySimulation : Lottery, Figure {
      override void draw();
 }

 Right now draw() overrides both methods, but you'd want to override 
 them separately. You could do so through an intermediate interface:

 class Figure2 : Figure {  void draw2() { return draw(); }  }
 class LotterySimulation : Lottery, Figure2 {
      override void draw();
      override void draw2();
 }

 There are a few problems with this, among which the fact that 
 LotterySimulation now cannot inherit another class; the one class slot 
 was occupied by Figure2.

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses. 
 What say you?

In fact, your example *still* does not work, since draw2 calls draw :) I think you meant: class Figure2 : Figure { abstract void draw2(); void draw() { return draw2();} } And I think actually, this still wouldn't work because LotterySimulation is overriding draw from Figure2. Maybe if you make it final in Figure2?

You're right. I haven't managed to do it yet (the one-leg renaming works in C++, though I forgot the details). All the more argument for defining the feature. Andrei
Sep 24 2009
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Walter and I discussed last night about contravariance and all and could  
 not find a compelling argument in favor of implementing contravariant  
 arguments right now. The feature is nontrivial to implement, potentially  
 surprising, and has a number of odd corner cases.

I find the general contravariance not to be that compelling, but for sure being able to implicitly cast delegates makes a lot of sense, since you take the overriding/overloading issues out of the equation. -Steve
Sep 24 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Walter and I discussed last night about contravariance and all and 
 could not find a compelling argument in favor of implementing 
 contravariant arguments right now. The feature is nontrivial to 
 implement, potentially surprising, and has a number of odd corner cases.

I find the general contravariance not to be that compelling, but for sure being able to implicitly cast delegates makes a lot of sense, since you take the overriding/overloading issues out of the equation. -Steve

I agree. Andrei
Sep 24 2009
prev sibling next sibling parent Marianne Gagnon <auria.mg gmail.com> writes:
 So I was thinking of this:
 
 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }
 
 This is easy to implement, scales well, and has good real world uses. 
 What say you?
 

One vote in favor :)
Sep 24 2009
prev sibling next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Andrei Alexandrescu wrote:
 ...
 
 So I was thinking of this:
 
 class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
 }
 
 This is easy to implement, scales well, and has good real world uses.
 What say you?
 
 
 Andrei

Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places.
Sep 24 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Daniel Keep:

 Why not go with what C# uses?
 
 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

Looks good enough, I can understand it. For the programmers out there it's positive to use a syntax already in use (especially if it's a good enough syntax). D design principles say D doesn't want to be revolutionary. In D originality is not a virtue when there are no net advantages, syntactical or otherwise. C# has other things worth copying beside explicit interface implementations :-) Bye, bearophile
Sep 24 2009
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Daniel Keep wrote:
 
 Andrei Alexandrescu wrote:
 ...

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses.
 What say you?


 Andrei

Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places.

Even better! Andrei
Sep 24 2009
prev sibling next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Daniel Keep wrote:
 Why not go with what C# uses?
 
 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }
 
 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud. Making it look like C# has bad sides too. Explicit overriding in C# always hides the member from the public view. So this "like C#" can easily backfire. ++andreis_suggestion; L.
Sep 24 2009
parent reply Max Samukha <spambox d-coding.com> writes:
On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
<lio lunesu.remove.com> wrote:

Daniel Keep wrote:
 Why not go with what C# uses?
 
 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }
 
 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

I actually like Andrei's suggestion a lot more! It's far more natural: try reading both versions out loud.

C# uses familiar syntax to qualify the function name. I think it's natural enough.
Making it look like C# has bad sides too. Explicit overriding in C#
always hides the member from the public view. So this "like C#" can
easily backfire.

According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces.
++andreis_suggestion;

I give my vote to C#'s syntax if D can adopt it.
L.

Sep 24 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Max Samukha wrote:
 On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
 <lio lunesu.remove.com> wrote:
 
 Daniel Keep wrote:
 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

try reading both versions out loud.

C# uses familiar syntax to qualify the function name. I think it's natural enough.
 Making it look like C# has bad sides too. Explicit overriding in C#
 always hides the member from the public view. So this "like C#" can
 easily backfire.

According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces.
 ++andreis_suggestion;

I give my vote to C#'s syntax if D can adopt it.
 L.


Yah. My take is that if we depart from familiarity, we ought to have a pretty darn good reason. I didn't know C# has the feature. Since it does with a reasonable notation, I'd say let's go for it. Andrei
Sep 24 2009
parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Andrei Alexandrescu wrote:
 Max Samukha wrote:
 On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
 <lio lunesu.remove.com> wrote:

 Daniel Keep wrote:
 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

try reading both versions out loud.

C# uses familiar syntax to qualify the function name. I think it's natural enough.
 Making it look like C# has bad sides too. Explicit overriding in C#
 always hides the member from the public view. So this "like C#" can
 easily backfire.

According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces.
 ++andreis_suggestion;

I give my vote to C#'s syntax if D can adopt it.
 L.


Yah. My take is that if we depart from familiarity, we ought to have a pretty darn good reason. I didn't know C# has the feature. Since it does with a reasonable notation, I'd say let's go for it. Andrei

Be careful with that reasoning. What about attributes? Properties? What about C# "var" vs. D "auto"? C# "using" vs. D "import"? In fact, what about the standard library? For myself, when learning a new programming language 10% of my time is spent on learning the language syntax and 90% on learning the standard library. Learning override(A) B vs. override A.B is NOP. L.
Sep 24 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lionello Lunesu wrote:
 Andrei Alexandrescu wrote:
 Max Samukha wrote:
 On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
 <lio lunesu.remove.com> wrote:

 Daniel Keep wrote:
 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

try reading both versions out loud.

natural enough.
 Making it look like C# has bad sides too. Explicit overriding in C#
 always hides the member from the public view. So this "like C#" can
 easily backfire.

effectively hidden. You can call them only through the interfaces.
 ++andreis_suggestion;

 L.


pretty darn good reason. I didn't know C# has the feature. Since it does with a reasonable notation, I'd say let's go for it. Andrei

Be careful with that reasoning. What about attributes? Properties? What about C# "var" vs. D "auto"? C# "using" vs. D "import"? In fact, what about the standard library?

I didn't say we need to do what C# does in particular. "auto" and "import" have precedents in other languages. A standard library is too large to copy wholesale.
 For myself, when learning a new programming language 10% of my time is
 spent on learning the language syntax and 90% on learning the standard
 library. Learning override(A) B vs. override A.B is NOP.

Then I take it you wouldn't mind override A.B :o). Andrei
Sep 24 2009
parent Lionello Lunesu <lio lunesu.remove.com> writes:
Andrei Alexandrescu wrote:
 Lionello Lunesu wrote:
 Andrei Alexandrescu wrote:
 Max Samukha wrote:
 On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
 <lio lunesu.remove.com> wrote:

 Daniel Keep wrote:
 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

try reading both versions out loud.

natural enough.
 Making it look like C# has bad sides too. Explicit overriding in C#
 always hides the member from the public view. So this "like C#" can
 easily backfire.

effectively hidden. You can call them only through the interfaces.
 ++andreis_suggestion;

 L.


pretty darn good reason. I didn't know C# has the feature. Since it does with a reasonable notation, I'd say let's go for it. Andrei

Be careful with that reasoning. What about attributes? Properties? What about C# "var" vs. D "auto"? C# "using" vs. D "import"? In fact, what about the standard library?

I didn't say we need to do what C# does in particular. "auto" and "import" have precedents in other languages. A standard library is too large to copy wholesale.
 For myself, when learning a new programming language 10% of my time is
 spent on learning the language syntax and 90% on learning the standard
 library. Learning override(A) B vs. override A.B is NOP.

Then I take it you wouldn't mind override A.B :o).

Do I mind?! I've suggested it before myself! http://www.digitalmars.com/d/archives/digitalmars/D/learn/3069.html#N3069 L.
Sep 24 2009
prev sibling parent reply Rainer Deyke <rainerd eldwood.com> writes:
Lionello Lunesu wrote:
 Be careful with that reasoning. What about attributes? Properties? What
 about C# "var" vs. D "auto"? C# "using" vs. D "import"? In fact, what
 about the standard library?

I wouldn't wind at all if D copied more from C#, and I don't even like C#. A natively compiled C# with extra features would be much more useful (and much easier to sell) than yet another incompatible object-oriented C variant. -- Rainer Deyke - rainerd eldwood.com
Sep 24 2009
parent Lionello Lunesu <lio lunesu.remove.com> writes:
Rainer Deyke wrote:
 Lionello Lunesu wrote:
 Be careful with that reasoning. What about attributes? Properties? What
 about C# "var" vs. D "auto"? C# "using" vs. D "import"? In fact, what
 about the standard library?

I wouldn't wind at all if D copied more from C#, and I don't even like C#. A natively compiled C# with extra features would be much more useful (and much easier to sell) than yet another incompatible object-oriented C variant.

You're right, I wouldn't mind either, though I would prefer keeping a D-feel to the new features. "override Interface.A()" feels like a loanword :) We have this great C-accent going on and it's partly this accent that defines us. Actually, I've always defended the use of English loan words in Dutch, so I guess that makes me pretty inconsistent :) L.
Sep 24 2009
prev sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
Max Samukha wrote:
 On Thu, 24 Sep 2009 23:55:57 +0800, Lionello Lunesu
 <lio lunesu.remove.com> wrote:
 
 Daniel Keep wrote:
 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

try reading both versions out loud.

C# uses familiar syntax to qualify the function name. I think it's natural enough.
 Making it look like C# has bad sides too. Explicit overriding in C#
 always hides the member from the public view. So this "like C#" can
 easily backfire.

According to Andrei's suggestion, the implemented functions are effectively hidden. You can call them only through the interfaces.

OK, but then we'll have to copy the other behavior as well: allowing explicit overrides and any non-explicit overrides will implement the matching interfaces that have not already been explicitly overridden. L.
Sep 24 2009
prev sibling parent reply =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Daniel Keep wrote:
 Andrei Alexandrescu wrote:
 ...

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world=20


 What say you?


 Andrei

Why not go with what C# uses? class LotterySimulation : Lottery, Figure { override void Lottery.draw(); override void Figure.draw(); } Just seems like a more obvious and natural place for it to me. D already uses this to disambiguate symbols in other places.

Except that the first option could be extended to allow overriding several methods from the same interface at once: class LotterySimulation : Lottery, Figure { override(Lottery) { void draw(); void foo(); } override(Figure) { void draw(); void foo(); } } Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Sep 26 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jérôme M. Berger wrote:
 Daniel Keep wrote:
 ...

 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.

Except that the first option could be extended to allow overriding several methods from the same interface at once: ... Jerome

"Except"? Which of my three statements does that apply to? The first and last are facts and the second is an opinion.
Sep 26 2009
parent =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Daniel Keep wrote:
=20
 J=E9r=F4me M. Berger wrote:
 Daniel Keep wrote:
 ...

 Why not go with what C# uses?

 class LotterySimulation : Lottery, Figure {
     override void Lottery.draw();
     override void Figure.draw();
 }

 Just seems like a more obvious and natural place for it to me.  D
 already uses this to disambiguate symbols in other places.



 several methods from the same interface at once:

 ...

         Jerome

"Except"? Which of my three statements does that apply to? The first and last are facts and the second is an opinion.

Obviously, it applies to the first, which isn't a fact but a question. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Sep 27 2009
prev sibling next sibling parent Max Samukha <spambox d-coding.com> writes:
On Thu, 24 Sep 2009 08:30:46 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

Walter and I discussed last night about contravariance and all and could 
not find a compelling argument in favor of implementing contravariant 
arguments right now. The feature is nontrivial to implement, potentially 
surprising, and has a number of odd corner cases.

One feature that does get requested often in C++ and Java is the ability 
to choose which class/interface contains the method you want to 
override. Consider:

interface Lottery {  void draw();  }
interface Figure {  void draw();  }

class LotterySimulation : Lottery, Figure {
     override void draw();
}

Right now draw() overrides both methods, but you'd want to override them 
separately. You could do so through an intermediate interface:

class Figure2 : Figure {  void draw2() { return draw(); }  }
class LotterySimulation : Lottery, Figure2 {
     override void draw();
     override void draw2();
}

There are a few problems with this, among which the fact that 
LotterySimulation now cannot inherit another class; the one class slot 
was occupied by Figure2.

So I was thinking of this:

class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
}

This is easy to implement, scales well, and has good real world uses. 
What say you?


Andrei

It would be a welcome addition. C# calls this feature 'explicit interface implementation' and has a different syntax:
class LotterySimulation : Lottery, Figure {
     void Lottery.draw() {};
     void Figure.draw() {};
}

The functions cannot be called through an instance of the class, only through the interfaces. In D: auto ls = new LotterySimulation; ls.draw(); Which 'draw' will be called?
Sep 24 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Sep 2009 10:30:09 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
  In the override(T) world, What does this do?
  auto ls = new LotterySimulation();
 ls.draw();
  ???
  I'm not sure this works...
  -Steve

That would be a compile-time error. You'd need to extract the interface you want to work with, and then call against it. In addition, LotterySimulation could offer convenience functions that do that.

OK. And it seems C# does the same thing, from what others are saying. Unfortunately, we don't have a distinct scope-resolution operator (like ::) so there wouldn't be a way to do this without casting to the interface, but I suppose in the cases where you are doing this, you aren't generally using the object directly, only through an interface. -Steve
Sep 24 2009
prev sibling next sibling parent Jeremie Pelletier <jeremiep gmail.com> writes:
Andrei Alexandrescu wrote:
 Walter and I discussed last night about contravariance and all and could 
 not find a compelling argument in favor of implementing contravariant 
 arguments right now. The feature is nontrivial to implement, potentially 
 surprising, and has a number of odd corner cases.
 
 One feature that does get requested often in C++ and Java is the ability 
 to choose which class/interface contains the method you want to 
 override. Consider:
 
 interface Lottery {  void draw();  }
 interface Figure {  void draw();  }
 
 class LotterySimulation : Lottery, Figure {
     override void draw();
 }

Doesn't the override keyword trigger an error here? There are no method to override since you're implementing it for the first time. Why would it matter to override both of them differently? You'd need extra work with the vtables to call either depending on the interface pointer its called from. And when called from LotterySimulation how would the compiler pick which one to call? To me it just seems backwards, I would just implement both algorithms in LotterySimulation.draw() since if you implement both interfaces you want that object to perform both draws, even if called from a Lottery interface you're still calling a LotterySimulation which is also aware of the Figure interface.
 Right now draw() overrides both methods, but you'd want to override them 
 separately. You could do so through an intermediate interface:
 
 class Figure2 : Figure {  void draw2() { return draw(); }  }
 class LotterySimulation : Lottery, Figure2 {
     override void draw();
     override void draw2();
 }
 
 There are a few problems with this, among which the fact that 
 LotterySimulation now cannot inherit another class; the one class slot 
 was occupied by Figure2.
 
 So I was thinking of this:
 
 class LotterySimulation : Lottery, Figure {
     override(Lottery) void draw();
     override(Figure) void draw();
 }
 
 This is easy to implement, scales well, and has good real world uses. 
 What say you?
 
 
 Andrei

From the news title I thought you meant override(T) where T is the covariant type for the contravariant override: class A { void foo(B); } class B:A { override(B) void foo(A); } Which could just as well be used to generate covariant boilerplate prologs :) As for the interface selection, I'm still asking, how would the compiler know what LotterySimulation.draw() calls into? Jeremie
Sep 24 2009
prev sibling next sibling parent Michal Minich <michal minich.sk> writes:
 So I was thinking of this:
 
 class LotterySimulation : Lottery, Figure {
 override(Lottery) void draw();
 override(Figure) void draw();
 }
 This is easy to implement, scales well, and has good real world uses.
 What say you?
 
 Andrei
 

I think this is well solved in C# http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx The syntax is simpler. Members implemented explicitly are not accessible thru variable of concrete class instance - they are only accessible thru variables of interface type (or when explicitly casted). If I understand you correctly, this is the same way as you propose for D.
Sep 24 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Walter and I discussed last night about contravariance and all and could 
 not find a compelling argument in favor of implementing contravariant 
 arguments right now. The feature is nontrivial to implement, potentially 
 surprising, and has a number of odd corner cases.

Something that may be useful, partially related: http://en.wikipedia.org/wiki/Multiple_dispatch http://en.wikipedia.org/wiki/Generic_function Bye, bearophile
Sep 24 2009
parent bearophile <bearophileHUGS lycos.com> writes:
 Something that may be useful, partially related:
 http://en.wikipedia.org/wiki/Multiple_dispatch
 http://en.wikipedia.org/wiki/Generic_function

Something similar to the CLisp syntax looks good enough for D (I think there's no need to add an explicit mark that reminds there's some runtime cost to be paid in this calls): void collideWith(Asteroid x, Asteroid y) { ...} void collideWith(Asteroid x, Spaceship y) { ...} ... Bye, bearophile
Sep 24 2009
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 24 Sep 2009 09:30:46 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:
 Walter and I discussed last night about contravariance and all and could  
 not find a compelling argument in favor of implementing contravariant  
 arguments right now. The feature is nontrivial to implement, potentially  
 surprising, and has a number of odd corner cases.

 One feature that does get requested often in C++ and Java is the ability  
 to choose which class/interface contains the method you want to  
 override. Consider:

 interface Lottery {  void draw();  }
 interface Figure {  void draw();  }

 class LotterySimulation : Lottery, Figure {
      override void draw();
 }

 Right now draw() overrides both methods, but you'd want to override them  
 separately. You could do so through an intermediate interface:

 class Figure2 : Figure {  void draw2() { return draw(); }  }
 class LotterySimulation : Lottery, Figure2 {
      override void draw();
      override void draw2();
 }

 There are a few problems with this, among which the fact that  
 LotterySimulation now cannot inherit another class; the one class slot  
 was occupied by Figure2.

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses.  
 What say you?


 Andrei

Umm, but what method would LotterySimulation.draw call? Would it be the override(Lottery) method or the override(Figure) method?
Sep 24 2009
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 So I was thinking of this:
 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }
 This is easy to implement, scales well, and has good real world uses.

auto x = new LotterySimulation; x.draw(); // what happens?
Sep 24 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 So I was thinking of this:
 class LotterySimulation : Lottery, Figure {
      override(Lottery) void draw();
      override(Figure) void draw();
 }
 This is easy to implement, scales well, and has good real world uses.

auto x = new LotterySimulation; x.draw(); // what happens?

Nolo compilendere. Andrei
Sep 24 2009
prev sibling parent Yigal Chripun <yigal100 gmail.com> writes:
On 24/09/2009 16:30, Andrei Alexandrescu wrote:
 Walter and I discussed last night about contravariance and all and could
 not find a compelling argument in favor of implementing contravariant
 arguments right now. The feature is nontrivial to implement, potentially
 surprising, and has a number of odd corner cases.

 One feature that does get requested often in C++ and Java is the ability
 to choose which class/interface contains the method you want to
 override. Consider:

 interface Lottery { void draw(); }
 interface Figure { void draw(); }

 class LotterySimulation : Lottery, Figure {
 override void draw();
 }

 Right now draw() overrides both methods, but you'd want to override them
 separately. You could do so through an intermediate interface:

 class Figure2 : Figure { void draw2() { return draw(); } }
 class LotterySimulation : Lottery, Figure2 {
 override void draw();
 override void draw2();
 }

 There are a few problems with this, among which the fact that
 LotterySimulation now cannot inherit another class; the one class slot
 was occupied by Figure2.

 So I was thinking of this:

 class LotterySimulation : Lottery, Figure {
 override(Lottery) void draw();
 override(Figure) void draw();
 }

 This is easy to implement, scales well, and has good real world uses.
 What say you?


 Andrei

in your code you tried to rename draw(), why not make this explicit? provide syntax to disambiguate by explicitly renaming the functions. for example: class A : Figure, Lottery { override(Figure.draw) void draw() { .. } override(Lottery.draw) void draw2() { .. } } please give more consideration to the idea than to my initial suggested syntax. btw, this is how Eiffel implements MI, the programmer specifies the mapping between names from the base class(es) and the subclass in order to solve ambiguities.
Sep 24 2009