Difference between revisions of "Multiple constraints"

m (The programmer selects a static type by using local variables or the object test)
Line 3: Line 3:
 
==Description==
 
==Description==
 
This article discusses issues which arise with multiple constrained type parameters.
 
This article discusses issues which arise with multiple constrained type parameters.
==Multiple constraints for generic type parameters==
+
==Formal generic type parameters with multiple constraints==
  
The new [http://www.ecma-international.org/publications/standards/Ecma-367.htm ECMA standard] for Eiffel introduces multi-constraint generic type parameters.
+
The new [http://www.ecma-international.org/publications/standards/Ecma-367.htm ECMA standard] for Eiffel introduces multi-constraint formal generic type parameters.
  
 
{|border="0" cellpadding="2" cellspacing="0" align="center"
 
{|border="0" cellpadding="2" cellspacing="0" align="center"
Line 45: Line 45:
 
Our interest is focused on the qualified feature call ''g.f'' of the example feature. With the dynamic binding semantics defined in section ''8.16.11'' of the ECMA standard, it makes a difference whether the static type of ''g'' is ''A'', ''B'' or ''C''. An illustration of the differences can be found in the [[Transposition]] article.
 
Our interest is focused on the qualified feature call ''g.f'' of the example feature. With the dynamic binding semantics defined in section ''8.16.11'' of the ECMA standard, it makes a difference whether the static type of ''g'' is ''A'', ''B'' or ''C''. An illustration of the differences can be found in the [[Transposition]] article.
  
The standard defines in section ''8.12.23'' what the base type of such a multiple constrained type parameter is. It is a fictitious class (denoted as a dashed class ''FICT'' in the diagram) 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 g) is. To obtain the correct feature, one needs the static and dynamic type of the target at runtime. Normally the base type of the target is taken as the static type. But we cannot take this fictitious base type as our static type, because, as can be seen in the diagram, it is outside of the conformance paths to X and therefore not usable with the current definition of dynamic binding.
+
The standard defines in section ''8.12.23'' what the base type of such a multiple constrained formal type parameter is. It is a fictitious class (denoted as a dashed class ''FICT'' in the diagram) 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 g) is. To obtain the correct feature, one needs the static and dynamic type of the target at runtime. Normally the base type of the target is taken as the static type. But we cannot take this fictitious base type as our static type, because, as can be seen in the diagram, it is outside of the conformance paths to X and therefore not usable with the current definition of dynamic binding.
  
 
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).
 
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).
Line 56: Line 56:
 
====Common ancestor====
 
====Common ancestor====
  
If we have a multi-constraint generic type parameter and a qualified feature call on a target of that type, 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 types which contain the feature ''f'' (in our case ''B'' and ''C'').
+
If we have a multi-constraint formal type parameter and a qualified feature call on a target of that type, 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 types which contain the feature ''f'' (in our case ''B'' and ''C'').
  
 
In our example we would set the static type of ''f'' to ''A'' and then execute the qualified feature call.
 
In our example we would set the static type of ''f'' to ''A'' and then execute the qualified feature call.
Line 68: Line 68:
 
====The programmer selects a static type by using local variables or the object test====
 
====The programmer selects a static type by using local variables or the object test====
  
A different idea is to disallow ambiguous qualified calls on targets of type ''G''. One would '''not''' be able to do a call like ''g.f'' because the feature ''f'' has ambiguities regarding dynamic binding.
+
A different idea is to disallow ambiguous qualified calls on targets of type ''G''.
 +
In our example it would '''not''' be valid to do the call ''g.f'' because the feature ''f'' is ambiguous.
  
 
As a consequence the programmer needs to resolve ambiguities in one of the following ways:
 
As a consequence the programmer needs to resolve ambiguities in one of the following ways:

Revision as of 13:54, 13 November 2006

Warning.png Warning: Warning: Article under development

Description

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

Formal generic type parameters with multiple constraints

The new ECMA standard for Eiffel introduces multi-constraint formal generic type parameters.

Example:

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

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

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
 
   g: G
 
   example is
      do       
         g.f      -- qualified feature call
      end
 
end

Our interest is focused on the qualified feature call g.f of the example feature. With the dynamic binding semantics defined in section 8.16.11 of the ECMA standard, it makes a difference whether the static type of g is A, B or C. An illustration of the differences can be found in the Transposition article.

The standard defines in section 8.12.23 what the base type of such a multiple constrained formal type parameter is. It is a fictitious class (denoted as a dashed class FICT in the diagram) 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 g) is. To obtain the correct feature, one needs the static and dynamic type of the target at runtime. Normally the base type of the target is taken as the static type. But we cannot take this fictitious base type as our static type, because, as can be seen in the diagram, it is outside of the conformance paths to X and therefore not usable with the current definition of dynamic binding.

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).

Possible solutions

To be able to use the type G one must provide a clear definition which static type is to use for a qualified feature call. An ambiguous feature, regarding the dynamic binding problematic, is a feature which is inherited through multiple constraining types. In our example this is the case for the feature f. It occurs in B and in C.

Common ancestor

If we have a multi-constraint formal type parameter and a qualified feature call on a target of that type, 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 types which contain the feature f (in our case B and C).

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

Properties of this solution:

  • All features can be directly called on a target of type G.
  • The static type of g may change depending on which feature is called.

The programmer selects a static type by using local variables or the object test

A different idea is to disallow ambiguous qualified calls on targets of type G. In our example it would not be valid to do the call g.f because the feature f is ambiguous.

As a consequence the programmer needs to resolve ambiguities in one of the following ways:

example is
      local
         b: B
      do 
         b := g
         b.f      -- qualified feature call with static type B
      end

The programmer explicitly choses static type B by assigning g to the local variable b.

example is
      do 
         check {bg: B | g } end
         bg.f  -- qualified feature call with static type B
      end

In this version the static type is chosen due to an object test.

Properties of this solution:

  • Not all feature calls can be applied to a target whose type is a multi-constraint generic.
  • The definition of the static type of every call remains straight forward.

Option

The renaming clause for multi-constraint types could be removed and name clashes could be regarded as ambiguous cases too. The user resolves it as shown above by choosing a static type explicitly.