10 COMBINING GENERICITY AND INHERITANCE 

Genericity and inheritance, the two fundamental mechanisms for generalizing classes, may
be combined in two fruitful ways. 

The first technique yields polymorphic data structures. Assume that in the generic class
LIST [G] the insertion procedure put has a formal argument of type G, representing the
element to be inserted. Then with a declaration such as 

     pl: LIST [POLYGON] 

the type rules imply that in a call pl.put ("...") the argument may be not just of type
POLYGON, but also of type RECTANGLE (an heir of POLYGON) or any other type
conforming to POLYGON through inheritance. 

The conformance requirement used here is the inheritance-based type compatibility rule; in
simple cases, V conforms to T if and only if V is a descendant of T. 

Structures such as pl may contain objects of different types, hence the name "polymorphic
data structure". Such polymorphism is, again, made safe by the type rules: by choosing an
actual generic parameter (POLYGON in the example) based higher or lower in the
inheritance graph, you extend or restrict the permissible types of objects in pl. A fully
general list would be declared as 

     LIST [ANY] 

where ANY, a Kernel Library class, is automatically an ancestor of any class that you may
write. 

The other mechanism for combining genericity and inheritance is constrained genericity.
By indicating a class name after a formal generic parameter, as in 

     VECTOR [T -> ADDABLE] 

you express that only descendants of that class (here ADDABLE) may be used as the
corresponding actual generic parameters. This makes it possible to use the corresponding
operations. Here, for example, class VECTOR may define a routine infix "+" for adding
vectors, based on the corresponding routine from ADDABLE for adding vector elements.
Then by making VECTOR itself inherit from ADDABLE, you ensure that it satisfies its own
generic constraint and enable the definition of types such as VECTOR [VECTOR [T]]. 

As you have perhaps guessed, unconstrained genericity, as in LIST [G], may be viewed as
an abbreviation for genericity constrained by ANY, as in 

          LIST [G -> ANY]. 

