Difference between revisions of "Multiple constraints"

Line 12: Line 12:
 
Example:
 
Example:
 
<code>[eiffel,N]
 
<code>[eiffel,N]
class GENERIC_CLASS [G -> {B, C }]
+
class C [G -> {A, B }]
 +
end
 +
</code>
 +
|}
 +
 
 +
Class C expects a type parameter that conforms to B and C.
 +
 
 +
====Explanation of the issue====
 +
Consider this example inheritance hierarchy together with the following code:
 +
 
 +
{|border="0" cellpadding="2" cellspacing="0" align="center"
 +
|-valign="top" -halign="center"
 +
|[[Image:Class_diagram_for_multiple_constraints_explanation.png|173px]]
 +
|
 +
Example:
 +
<code>[eiffel,N]
 +
class GENERIC_CLASS [G -> {B, C}]
  
 
feature
 
feature
Line 18: Line 34:
 
   f: G
 
   f: G
  
   t (g: G) do end
+
   h (g: G) is
 +
      do
 +
        -- something
 +
      end
 +
 
 
   example is
 
   example is
        -- issue
 
 
       do       
 
       do       
 
         f.a      -- Line 1: feature call
 
         f.a      -- Line 1: feature call
 
 
 
       end
 
       end
  
Line 30: Line 47:
 
</code>
 
</code>
 
|}
 
|}
 +
Let's first have a look at the qualified feature call ''f.a'' on line 1 of the example feature. The standard defines in section ''8.12.23'' what the base type of such a multiple constrained type parameter is. It is a fictive class (denoted as a dashed class ''FICT'' in the diagramm) which inherits from all constraint classes and to which a possible renaming is applied. Dynamic binding requires a clear notion of what the static type of a target (here f) is. Because to obtain the correct feature one needs the static and dynamic type of the target at runtime. One normally would take the base type of the target as the static type. But we cannot take this fictive base type as our static type because, as can be seen in the diagram, he is outside of the conformance paths to X and therefore not usable with the current definition of dynamic binding in section ''8.16.11''.
  
The semantic given to the code above is, that an actual parameter passed for G must be conform to both classes: B and C.
+
If B and/or C redefine the feature ''f'' the problem is resolved by renaming and one can chose for which conformance path the feature is called. If until the level of ''{B,C}'' no redefinition of feature ''f'' has occured, the decision which static type to use is getting more complicated: The feature ''f'' could for exmaple be redefined in ''B2''and/or ''C2''.
 +
In that case ''X'' would then have to select one of them. This yields is an ambiguity which the current ECMA Standard (version 2) does not resolve because no proper definition for the static type is given in this case.
  
====Explanation of the issue====
+
The definition of this fictitious type ''FICT'' can only be used to clearly define the set of available features to instances of type G. It can not be used to define the semantic of a qualified feature call (like f.a).
Consider the above example together with the following inheritance hierarchy:
+
  
[[Image:Class_diagram_for_multiple_constraints_explanation.png|173px]]
+
====Proposed semantic: ====
  
The standard defines in section 8.12.23 what the basic type of such a multiple constraint formal generic is. It is a fictive class (denoted as a dashed "{B,C}" class in the diagramm) which inherits from all constraint classes and to which a possible renaming is applied. Dynamic binding requires a clear notion of what the static type of a target (here f) is. One normally would take the basic type of the target as the static type. which is then used for the call.
+
One possible solution is, that if we have a multiple constrained type parameter and a qualified feature call on a feature with one common body, we define the static type to be the type of the class which introduced the current version of the called feature body. This must be a common ancestor of the constraining class which contain the feature.
  
If B and/or C redefine the feature ''f'' the problem is resolved by renaming and one can chose from which branch the feature is called. If until the level of ''{B,C}'' no redefinition of feature ''f'' has occured the decision which static type to use is getting more complicate: The feature ''f'' could for exmaple be redefined in ''B' ''and/or ''C' ''. In taht case ''X'' would then select one of them. This yields is an ambiguity which the current ECMA Standard (version 2) does not resolve.  
+
In our example we would set the static type of ''f'' to ''A'' and then execute the qualified feature call.
  
The definition of this virtual type ''{B,C}'' can only be used to clearly define the set of available features to instances of type G. It can not be used to define the semantic of a qualified feature call (like f.a).
+
This is somehow reasonable because if there would not be any children, we would execute the feature ''f'' defined in ''A''. If we set the static type to A we ensure that whatever occurs to ''f'' we will always execute the feature which the programmers selects to be the right feature for static type A.
 
+
So the question the ECMA Standard does not answer is: What is the static type of a formal generic which has multiple constraints?
+
 
+
====Proposed semantic: ====
+

Revision as of 15:51, 30 October 2006

Description

This article discusses issues which arise in conjunction with multiple constrained type parameters.

New multiple constraints for generic parameters

With the new ECMA standard for Eiffel multiple constraints for type parameters were introduced.

Example:

class C [G -> {A, B }]
end

Class C expects a type parameter that conforms to B and C.

Explanation of the issue

Consider this example inheritance hierarchy together with the following code:

Class diagram for multiple constraints explanation.png

Example:

class GENERIC_CLASS [G -> {B, C}]
 
feature
 
   f: G
 
   h (g: G) is
      do
         -- something
      end
 
   example is
      do       
         f.a      -- Line 1: feature call
      end
 
end

Let's first have a look at the qualified feature call f.a on line 1 of the example feature. The standard defines in section 8.12.23 what the base type of such a multiple constrained type parameter is. It is a fictive class (denoted as a dashed class FICT in the diagramm) which inherits from all constraint classes and to which a possible renaming is applied. Dynamic binding requires a clear notion of what the static type of a target (here f) is. Because to obtain the correct feature one needs the static and dynamic type of the target at runtime. One normally would take the base type of the target as the static type. But we cannot take this fictive base type as our static type because, as can be seen in the diagram, he is outside of the conformance paths to X and therefore not usable with the current definition of dynamic binding in section 8.16.11.

If B and/or C redefine the feature f the problem is resolved by renaming and one can chose for which conformance path the feature is called. If until the level of {B,C} no redefinition of feature f has occured, the decision which static type to use is getting more complicated: The feature f could for exmaple be redefined in B2and/or C2. In that case X would then have to select one of them. This yields is an ambiguity which the current ECMA Standard (version 2) does not resolve because no proper definition for the static type is given in this case.

The definition of this fictitious type FICT can only be used to clearly define the set of available features to instances of type G. It can not be used to define the semantic of a qualified feature call (like f.a).

Proposed semantic:

One possible solution is, that if we have a multiple constrained type parameter and a qualified feature call on a feature with one common body, we define the static type to be the type of the class which introduced the current version of the called feature body. This must be a common ancestor of the constraining class which contain the feature.

In our example we would set the static type of f to A and then execute the qualified feature call.

This is somehow reasonable because if there would not be any children, we would execute the feature f defined in A. If we set the static type to A we ensure that whatever occurs to f we will always execute the feature which the programmers selects to be the right feature for static type A.