digitalmars.D - Polymorphic catcalls
- Regan Heath (42/42) Apr 17 2012 A colleague of mine here at work is a fan of Eiffel and recently passed ...
- Famous (9/9) Apr 17 2012 I think that one cannot expect the compiler to detect semantic
- Famous (4/4) Apr 18 2012 See also:
- Kagamin (2/2) Apr 19 2012 Huh? Is DbC viable at all if in practice subtype inevitably break
- Timon Gehr (3/5) Apr 19 2012 I am not sure if that is what you mean, but contracts specify behavior,
- Kagamin (6/8) Apr 20 2012 They don't, but they don't live in vacuum either, they have to
A colleague of mine here at work is a fan of Eiffel and recently passed this example of a problem with polymorphism which Bertrand Meyer called a "Catcall" ('Cat' stands for 'Changed Availability or Type') The original article by Meyer is here: http://archive.eiffel.com/doc/manuals/technology/typing/cat.html My colleague's example Eiffel code exhibiting the "problem" is here.. SKIER Eiffel class: http://www.jurjevic.org.uk/programming/eiffel/examples/catcall/test/skier_chart.html BOY Eiffel class: http://www.jurjevic.org.uk/programming/eiffel/examples/catcall/test/boy_chart.html GIRL Eiffel class: http://www.jurjevic.org.uk/programming/eiffel/examples/catcall/test/girl_chart.html This is how a boy can hope to share a room with a girl in Eiffel (at present Eiffel compiler is incapable of detecting the error and exception is thrown at run time): http://www.jurjevic.org.uk/programming/eiffel/examples/catcall/test/example.html His description of why it occurs is.. "That is because of the polymorphic assignment `s := b' and the fact that in Eiffel it is allowed in a descendant class to covariantly change formal argument types (in BOY class in 'share' call 'other' argument is covariantly changed from SKIER to BOY, in GIRL class in 'share' call 'other' argument is covariantly changed from SKIER to GIRL)." In D, we're not allowed to change the formal argument type of an interface method when we implement it (I believe) so if we were to attempt to implement something like this we'd be casting the "Skier other" to a "Boy otherBoy" in the overridden method and then asserting/throwing on the resulting null when a Girl was passed. So, we'd also solve the problem by detecting it at runtime. But it got me wondering, is it at all possible to solve the problem at compile time.. I suspect not as by the time you assign an instance of a Boy or Girl to a variable of type Skier I think you might lose the ability to enforce anything WRT it's underlying/derived type at compile time. I suspect the compiler would have to do some sort of code inspection to be able to determine the derived type at compile time, and that's a bit much to ask to solve something that's really just a consequence of polymorphism itself IMO. But then, I'm pretty terrible when it comes to using D's compile time/generic/generative features so I thought I'd post this and see if anyone could come up with anything. Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 17 2012
I think that one cannot expect the compiler to detect semantic errors. As far as I can see it the initial object oriented model is unsound. Within the model 'BOY' and 'GIRL' are not valid substitutes for 'SKIER' since they fail to satify the Liskov substitution principle: http://en.wikipedia.org/w/index.php?title=Liskov_substitution_principle&oldid=484745299 Cheers, Famous
Apr 17 2012
See also: http://tecomp.sourceforge.net/index.php?file=doc/papers/lang/catcall_solution.txt Cheers, Famous
Apr 18 2012
Huh? Is DbC viable at all if in practice subtype inevitably break supertype's contract?
Apr 19 2012
On 04/19/2012 12:38 PM, Kagamin wrote:Huh? Is DbC viable at all if in practice subtype inevitably break supertype's contract?I am not sure if that is what you mean, but contracts specify behavior, they do not usually care about types in detail.
Apr 19 2012
On Thursday, 19 April 2012 at 16:01:59 UTC, Timon Gehr wrote:I am not sure if that is what you mean, but contracts specify behavior, they do not usually care about types in detail.They don't, but they don't live in vacuum either, they have to live in real code (if we're going to use them in real code), where they should play nicely with inheritance or their usability is questionable - that's what I mean. Who's interested in their possible usability in a hypothetical environment?
Apr 20 2012
I think that Design by Contract is reasonable in theory and practice. As far as I know, in contrast to Eiffel, D does not allow covariant method arguments in subclasses. This is a necessary condition for structural correctness of the object oriented model. However, this condition is not sufficient. In order to ensure correctness, a proof is necessary. Design by Contract generally cannot provide a proof but only cover some specific test cases. In practice, if done well, Design by Contract often gives sufficient reason to trust a piece of code. Particularly, I do not share your fear that, in practice, a subtype 'inevitably' breaks a supertype's contract. On the contrary, running into such a situation should make the developer rethink his model. Cheers, Famous
Apr 21 2012
The Little Willy example applies to D just fine. When served wrong drink, Little Willy has little choice but to throw an exception. This seems like a strengthening of a Customer's contract, doesn't it? It doesn't matter how the typecheck is done technically. And this strengthening seems to be inevitable in practice.
Apr 21 2012
On Saturday, 21 April 2012 at 13:52:20 UTC, Kagamin wrote:The Little Willy example applies to D just fine. When served wrong drink, Little Willy has little choice but to throw an exception. This seems like a strengthening of a Customer's contract, doesn't it? It doesn't matter how the typecheck is done technically. And this strengthening seems to be inevitable in practice.It's not inevitable, it's wrong design. While each square is a rectangle in mathematics this is not necessarily true in an object oriented model. Cheers, Famous
Apr 21 2012