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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.