catcalls/convert
Raphael Mack <[email protected]>
| Newsgroups | gmane.comp.lang.eiffel.smalleiffel |
|---|---|
| Organization | ETH Zürich |
| Message-ID | <52f9148582135b2101eae49a5c906302@bertrand> |
Hello,
I played around with catcalls and found the interesting case:
deferred class FOOD
inherit ANY
redefine out end
feature
out: STRING is do Result := "food" end
end
class SALAD, MEAT
inherit FOOD
redefine out end
feature
out: STRING is do Result := ["salad"|"meat"] end
end
class ANIMAL
feature
eat(food: FOOD) is
do
io.put_string("ANIMAL eating " + food.out)
end
end
class DOG
inherit ANIMAL
redefine
eat
end
feature
eat(food: MEAT) is
do
io.put_string("DOG eating " + food.out)
end
end
class A
creation
make
feature
make is
local
a: ANIMAL
m: MEAT
s: SALAD
do
create {DOG}a
create m -- (XX)
create s
a.eat(s)
end
end
In this code everything seems to work: the compiler doesn't warn you
and the dog really eats meat. If line XX is removed - what doesn't
change anything - the program crashes at runtime with "Target Type
"SALAD" is not valid". Of cause this is ok, since we triggered a
catcall. With lin XX the compiler seems to optimize and "knows" in
feature eat of class DOG we print the string "meat". This behavior is
ok, because the whole construct is invalid, but for debugging it would
be great if one would be warned or it would crash in both cases at
runtime.
I found a paper about "Type-safe covariance: Competent compilers can
catch all catcalls". It suggests this recast mechanism to "convert"
the argument of eat dynamically if it doesn't conform to the actual
type (here from FOOD to MEAT). Two questions about this:
There is this convert construct stated by B. Meyer (and (paritally?)
implemented by ISE) to get rid of the balancing rule. Why do we need
both? Wouldn't it be possible to replace recast just by requiring a
convertion feature for the corresponding types?
The recast-function would be in the client class (here DOG). This
seems a bit strange at first. Why should class DOG be able to convert
a food to a meat?
One can answer both questions in one: With recast one has the
possibility to know more about the concret case espesially if there is
more than one polymorphic argument with a possible catcall. But are
there really such cases? If there is another MEAT-eating class LION
one has to write two (similar) recast functions, both converting FOOD
to MEAT...
By the way: it's even worse with ise: the dog eats salad in both
cases...
A more general question: Is there a real-live example where the
recasting/converting would be really useful? - If one can convert the
types automatically whouldn't they differ in so little, that the more
general type wouldn't be sufficant to model both classes? For me it
seems, that if one needs two classes, they are too different to
generate the special object from the more general.
Did research go on in this field? What is the state of the
recast-construct in ECMA? What is the strategy of handling catcalls in
SE?
To resume the question about conformance of agents from last week
(thanks for the link to the article - it was very interesting to read;
thanks for writing it SE-team!): I have a few question about the
article:
What is the main difference between the catcall example given in this
email and the version from the paper using agents? Wouldn't the
recast/convert-approach solve the agent-porblem, too?
In the paper the authors state on page 137 "the rules define
conformance rules, this hat nothing to do with covariance or
contravariance". I don't understand that - co/contravariance is about
conformance, too, isn't it? so what's the difference?
BTW: The profiling-option is pure fun, it's great!
Thanks for your patience with such a newbie like me.
Rapha