Thursday, June 15, 2006


Catcalls: 1992 vs. 2007

Reichenbach Etienne noticed that ISE Eiffel crashed with a segmentation fault if he compared a STRING with a STRING_32:
create {STRING_32} string_1.make_from_string ("String 1")
create {STRING} string_2.make_from_string ("String 2")
if string_1 < string_2 then ...
Emmanuel Stapf replied:
This behavior is expected, it is called a CATCALL in Eiffel terminology. The good news is that in the ECMA specification those won't occur anymore, but this hasn't been implemented yet in our compiler.
Back in 1992, the reply would have been:
This behavior is expected, it is called a System Validity Error in Eiffel terminology. The good news is that in the ETL specification those won't occur anymore, but this hasn't been implemented yet in our compiler.
The ECMA solution appears to entail a runtime penalty, which we can accept more readily in 2006 than we could have in 1992. The loss of expressiveness caused by the 1992 ETL solution and the later "no polymorphic catcalls" solution probably made them both non-starters.

Where does the runtime penalty come from?
Colin, the runtime penalty comes from ECMA section 8.14.5:

"...the type of a covariant argument will have to be declared as detachable: you cannot redefine f(x: T) into f(x: U) even if U conforms to T; you may, however, redefine it to f(x: ?U). This forces the body of the redefined version, when applying to 'x' any feature of 'f', to ensure that the value is indeed attached to an instance of U by applying an Object_test, for example of the form

if {x: U} y then y.feature_of_U else ... end

This protects the program from catcalls..."
These kinds of errors are completely ununderstandable. Even by me.

I understand catcalls, but using equal to compare strings should just have worked or failed to compile. It is so unbelievably common that it should have been caught.

Note that the Gobo compiler spits outs a warning for these I believe.
I was not there in 1992, but ETL2 did not address those at all. So which ETL specification did you refer to?
But this is only for routines that covariantly re-define an argument. Which, I think, is very rare.

And it's only informative text - as far as I can see it's a correctness condition - you are not forced to write it - you can have incorrect code (just as now).

So there's only an overhead if you decide to make your code bulet-proof.
Emmanuel: ETL2 page 367, validity rule VUGV: "A call is valid if and only if it is both class-valid and system-valid". Pages 357-372 discuss system-level validity in more depth.

Those pages cover covariant argument redefinitions such as this one (Reichenbach's example).

ETL2 system validity checking requires calculating the dynamic type set of an expression, which no Eiffel compiler implemented (although Eric Bezault wrote a lint-like checking tool that does this).
Colin: ECMA Eiffel does indeed force you to check this (otherwise you cannot make any call on the covariantly-redefined argument).

This will be enforced by ECMA Eiffel's rules of attachment (when implemented).

There's a run-time overhead if you decide to make your code compilable, but at least your application won't crash with a system validity error.
The use of detachable types as
a solution to covariance type
errors is only a partial solution
suffering from the problem of
being, in its essence, dynamic

In the callee object is is
ensured that no qualified call
is done using incorrect types
(which is good).
However, one wonders, if a
conditional instruction is used,
what should be putted in the else
part (raise an exception?).

Also, this approach does not solve
the caller problem. It is statically
valid to call routines using wrong
types (due to covariance).
So we are in the presence of
a dynamic approach to the covariance
problem (as opposed to the original
system validity rule and the
CAT-Calls proposal).

In my opinion a better (static)
approach to this problem would
be an appropriate multiple
dispatch mechanism.
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?