Detachable types
Contents
Introduction
This solution allows covariantly redefined features only to use detachable types. Through this mechanism, an object test is necessary before an argument can be used. This forces the programmer to test arguments for validity.
This is specified in the ECMA Eiffel standard 2nd edition of June 2006.
Syntax
No new syntax is necessary.
Semantics
In this solution, it is only allowed to covariantly redefine arguments to detachable types. This ensures that an object test is done before the use of an argument. If now a catcall happens, the object test will fail. Since the argument is of detachable type, the programmer has to handle the case where Void is passed anyway and this also handles the catcall.
Examples
Cats and dogs
The definition of the CAT class changes as follows:
class CAT inherit ANIMAL redefine eat end feature eat (food: ? CAT_FOOD) do if {cat_food: CAT_FOOD} food then -- Use `cat_food' else -- either Void or an argument of type FOOD passed end end end
Issues
Weak covariance support
See article on dev.eiffel.com.
Generics
With the current conformance of generics, different generic derivations can be seen as if they covariantly redefined the features with formal generic parameters. For example feature put
from the class LIST
if you look at the signature of LIST [ANY]
compared to LIST [STRING]
. As with anchored types as parameters, you would also have to specify that all formal generic parameters need to be detached. This would mean that all classes which use generic parameters always have to use object tests to use the generic parameters, and Void-safety cannot be expressed on the type system level which would remove the main benefit of attached types in the context of generics.
Expanded types
The type rule specified by ECMA (VTCT, 8.11.8) defines that an expaned type cannot have an attachment mark since Void is not a valid value for it. Given that covariant feature redeclaration, especially anchored types for arguments, can only occur with detached types, this means that arguments cannot be covariantly redefined into expaned types.
The base classes like INTEGER
which currently inherit from NUMERIC
which only defines it's arguments as like Current
would be invalid in their current form. Also if formal generic parameters need to be detached as explained above, generic derivations would not be allowed for expaned types if the formal generic occurs as a parameter of a feature. Especially LIST [INTEGER]
would not be possible.
Conclusion
The problems arise partially due to the fact that two concepts are mixed:
- Attachable/detachable types: A type
? T
can be attached to an object of type T or not attached at all (i.e. Void) - Catcall arguments: In a catcall, the type of the argument can either be the expected type or the type of an ancestor version of the feature.
By using detachable types to solve catcalls, the notion of a detachable type is expaned to be able to hold types of all ancestors as well.
In addition to this, the problems with generics and expanded types show that this solution does severly limit the usefulness of covariance.