Difference between revisions of "Single-level call rule and generics"

m (Monomorph formal generics)
(Monomorphic formal generics)
 
(7 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
== Problem ==
 
== Problem ==
  
The single-level call rule says that every call has to be valid for all possible dynamic types of an entity. So for a formal generic <e>G</e> this means that the call has to be valid for all possible descendants of the constraint (or at least for every instantiation which happens in a system).
+
The single-level call rule says that every call has to be valid for all possible dynamic types of an entity. So for a formal generic <e>G</e> this means that the call has to be valid for all possible descendants of the constraint (or at least for every generic derivation that occurs in a system).
  
 
Let's look at an example using <e>NUMERIC</e>:
 
Let's look at an example using <e>NUMERIC</e>:
Line 27: Line 27:
 
</e>
 
</e>
  
The problem is that the formal generic <e>G</e> is always assumed to be of any type which satisfies the constraint, so normally the formal generic is polymorph.
+
The problem is that the formal generic <e>G</e> is always assumed to be of any type which satisfies the constraint, so normally the formal generic is polymorphic.
  
As the above example show, the use of features on formal generic parameters which are covariantly redefined is severely limited. But as the purpose of <e>NUMERIC</e> is exactly to allow creation of generic algorithms over numeric types, this has to be addressed (Note that also <e>COMPARABLE</e> is a problem).
+
As the above example show, the use of features on formal generic parameters which are covariantly redefined is severely limited. But as the purpose of <e>NUMERIC</e> is exactly to allow creation of generic algorithms over numeric types, this has to be addressed (Note that <e>COMPARABLE</e> is also a problem).
  
 
== Possible solutions ==
 
== Possible solutions ==
  
=== Monomorph formal generics ===
+
=== Monomorphic formal generics ===
  
The first idea is to be able to mark a formal generic as monomorph:
+
The first idea is to be able to mark a formal generic as monomorphic:
 
<e>
 
<e>
class X [monomorph G -> NUMERIC]
+
class X [monomorphic G -> NUMERIC] feature
  
 
   f (g1, g2: G): G
 
   f (g1, g2: G): G
Line 47: Line 47:
 
</e>
 
</e>
  
The generic class can then only be instantiated with monomorphic types, i.e. using [[interval types]] <e>X [INTEGER..INTEGER]</e> or <e>X [REAL..REAL]</e>.
+
The class can then only be generically derived with monomorphic types, i.e. using [[interval types]] <e>X [INTEGER..INTEGER]</e> or <e>X [REAL..REAL]</e>.
 +
 
 +
  [Comment by BM 5 Nov 2007: this does not seem desirable as there is nothing
 +
  wrong with the class, only with the feature.]
  
 
For the check we can now assume that <e>G</e> will be monomorphic. This helps a little bit further: For every feature argument which is <e>like Current</e> we can assume that the exact type will be given. But this works only for covariant features which have <e>like Current</e> arguments which are never redefined into something else. Take the following classes for an example:
 
For the check we can now assume that <e>G</e> will be monomorphic. This helps a little bit further: For every feature argument which is <e>like Current</e> we can assume that the exact type will be given. But this works only for covariant features which have <e>like Current</e> arguments which are never redefined into something else. Take the following classes for an example:
Line 75: Line 78:
  
 
<e>
 
<e>
class X [monomorph G -> A]
+
class X [monomorphic G -> A]
 
feature
 
feature
 
   f
 
   f
Line 88: Line 91:
 
The call to <e>g1.f</e> is not valid since <e>G</e> could be of type <e>C</e>, and then the argument has to be of type <e>D</e>. So now, not even the <e>like Current</e> feature is callable with monomorphic generics. Basically it is the same as the declaration without ''monomorphic'' for the generic.
 
The call to <e>g1.f</e> is not valid since <e>G</e> could be of type <e>C</e>, and then the argument has to be of type <e>D</e>. So now, not even the <e>like Current</e> feature is callable with monomorphic generics. Basically it is the same as the declaration without ''monomorphic'' for the generic.
  
So this solution works only for the case of <e>like Current</e> features which are never redefined. Only then it can be guaranteed for a monomorphic generic formal, that the signature will match the formal generic exactly. Other covariant features have still to be valid for all possible descendants.
+
So this solution works only for the case of <e>like Current</e> features never change the signature. Only then it can be guaranteed for a monomorphic generic formal, that the signature will match the formal generic exactly. Other covariant features have still to be valid for all possible descendants.
  
 
For the case of <e>NUMERIC</e> and <e>COMPARABLE</e> the use of monomorphic formal arguments would work as they define only <e>like Current</e> features which are normally kept that way in subclasses. A more general mechanism would be nice but at the moment it is unclear how such a mechanism should look like.
 
For the case of <e>NUMERIC</e> and <e>COMPARABLE</e> the use of monomorphic formal arguments would work as they define only <e>like Current</e> features which are normally kept that way in subclasses. A more general mechanism would be nice but at the moment it is unclear how such a mechanism should look like.

Latest revision as of 09:25, 5 November 2007

Problem

The single-level call rule says that every call has to be valid for all possible dynamic types of an entity. So for a formal generic G this means that the call has to be valid for all possible descendants of the constraint (or at least for every generic derivation that occurs in a system).

Let's look at an example using NUMERIC:

class X [G -> NUMERIC]
 
feature
 
  f (g1, g2: G): G
    do
      Result := g1 + g2
    end
 
end

Here, the call to + has to be valid for all possible descendants of NUMERIC. Since the signature of the feature is like Current, the call is never valid. This has to be the case as otherwise, the following code would produce a catcall:

x: X [NUMERIC]
x.f (1, 1.0)

The problem is that the formal generic G is always assumed to be of any type which satisfies the constraint, so normally the formal generic is polymorphic.

As the above example show, the use of features on formal generic parameters which are covariantly redefined is severely limited. But as the purpose of NUMERIC is exactly to allow creation of generic algorithms over numeric types, this has to be addressed (Note that COMPARABLE is also a problem).

Possible solutions

Monomorphic formal generics

The first idea is to be able to mark a formal generic as monomorphic:

class X [monomorphic G -> NUMERIC] feature
 
  f (g1, g2: G): G
    do
      Result := g1 + g2
    end
 
end

The class can then only be generically derived with monomorphic types, i.e. using interval types X [INTEGER..INTEGER] or X [REAL..REAL].

  [Comment by BM 5 Nov 2007: this does not seem desirable as there is nothing
  wrong with the class, only with the feature.]

For the check we can now assume that G will be monomorphic. This helps a little bit further: For every feature argument which is like Current we can assume that the exact type will be given. But this works only for covariant features which have like Current arguments which are never redefined into something else. Take the following classes for an example:

class A
feature
  f (a: like Current) do end
end
 
class B
inherit A
end
 
class C
inherit A redefine f
feature
  f (a: D) do end
end
 
class D
inherit C
end

Now assume the following generic class:

class X [monomorphic G -> A]
feature
  f
    local
      g1, g2: G
    do
      g1.f (g2)
    end
end

The call to g1.f is not valid since G could be of type C, and then the argument has to be of type D. So now, not even the like Current feature is callable with monomorphic generics. Basically it is the same as the declaration without monomorphic for the generic.

So this solution works only for the case of like Current features never change the signature. Only then it can be guaranteed for a monomorphic generic formal, that the signature will match the formal generic exactly. Other covariant features have still to be valid for all possible descendants.

For the case of NUMERIC and COMPARABLE the use of monomorphic formal arguments would work as they define only like Current features which are normally kept that way in subclasses. A more general mechanism would be nice but at the moment it is unclear how such a mechanism should look like.

Remodeling library

Another way to solve the problem of NUMERIC and COMPARABLE would be to change the library. As these classes have mostly like Current arguments and result types, they can be modeled via generics in the first place.

For example:

class NUMERIC [G -> NUMERIC [G]]
feature
  infix "+" (other: G): G
end
 
class COMPARABLE [G -> COMPARABLE [G]]
feature
  less_than (other: G): BOOLEAN
end

With this approach, the use of the general class NUMERIC and COMPARABLE will become more complicated, but since they appear in libraries most of the time it could be done.