In SK each user-defined class must be either subtype of VALUE (indicated by the keyword value) or subtype of REFERENCE (default). Because SK does not allow supertyping, it isn't possible to have user-defined supertypes of both VALUE and REFERENCE as is possible in S1. Because S1 requires that an instance of a type parameter must be a subtype of type parameter bounds, forbidding common supertypes of VALUE and REFERENCE would require a different version of a class for reference typed parameters and value typed parameters. In SK, the problem is solved by structural conformance, i.e. the instance of a generic parameter must conform to its type bound, but need not to be a subtype. This is why supertyping does not exist in SK.
Structural parameter bounds are further motivated by the following
scenario. Users should be able to use libraries by multiple
independent developers without changing the source of the libraries.
Suppose a library contains a generic class A(T<Y) and the class
defining type bound Y. Suppose further that library
contains
class X which structurally conforms to Y. Because of structural
conformance in SK it is legal to instantiate T with X, i.e. to
write A(X). In S1 this is only legal if before either Y is declared
as a supertype of X or X is declared as a subtype of Y. Hence S1
requires changing
or
or additional code to allow the
expression A(X).
In general, SK structural parameter bounds can be translated to S1 by
introducing an appropriate abstract class. SK parameter bounds allow
the parameter to be structurally conformant instead of requiring a
subtype. This implies that in a class , a T can not be
assigned to a
because it might not be a subtype. S1 parameter
bounds allow code which is not legal in SK, and S1 classes
parameterized this way would need special handling to be expressed in
SK. For example:
has no simple translation in SK. In SK all requirements on generic parameters are derived from the class body and checked upon instantiation of the generic parameter.
One motivation of structural parameter bounds was to make it possible to use libraries written by multiple independent developers. For the same reason, S1 prohibits some forms of overloading which SK allows. S1 forbids overloading between two abstract types with no subtype relation between them, while SK allows it. For example:
This code is illegal in S1 unless subtypes from
or vice
versa.
It might be convenient to have such an overloading when
and
are not anticipated to have a common subtype. Note that
and
are not defined in either
or
, but in
some other library on which both
and
depend. In this
example,
and
cannot be compiled together, although each
compiles independently. When allowing such overloading, there is the
implicit constraint that no class may be created which subtypes from
and
at once. Neither S1 nor SK can express this
constraint, but S1 chooses to disallow it; L1 and L2 cannot be
composed unless the type system guarantees that any subtypes can be
disambiguated with a most specific type. SK allows such overloading
but the compiler can discover and output such implicit constraints.