[Next] [Previous] [Up] [Top] [Contents] [Index]

3.3 Type and Signature Declarations

3.3.8 Discussion

Subtyping and conformance in Cecil is explicit, in that the programmer must explicitly declare that an object conforms to a type and that a type is a subtype of another type. These explicit declarations are verified as part of type checking to ensure that they preserve the required properties of conformance and subtyping. Explicit declarations are used in Cecil instead of implicit inference of the subtyping relations (structural subtyping) for two reasons. One is to provide programmers with error-checking of their assumptions about what objects conform to what types and what types are subtypes of what other types. Another is to allow programmers to encode additional semantic information in the use of a particular type in additional to the information implied by the type's purely syntactic interface. Both of these benefits are desirable as part of Cecil's goal of supporting production of high-quality software. To make exploratory programming easier, a programming environment tool could infer the greatest possible subtype relationships (i.e., the implicit "structural" subtyping relationships) for a particular object and add the appropriate explicit subtype declarations automatically.

Separating subtyping from implementation inheritance increases the complexity of Cecil. A simpler language might provide only subtyping, and restrict objects to inherit code only from their supertypes; Trellis takes this approach, for example. However, there is merit in clearly separating the two concepts, and allowing inheritance of code from objects which are not legal supertypes. Studies have found this to be fairly common in dynamically-typed languages [Cook 92]. With the current Cecil design, the only way that an object might not be a legal (structural) subtype of an object from which it inherits is if the child overrides a method of the parent and restricts at least one argument type declaration, a relatively rare occurrence. However, Cecil may eventually support filtering and transforming operations as part of inheritance, such as the ability to exclude operations, to rename operations, or to systematically adjust the argument types of operations, and so would create more situations in one object would inherit from another without being a subtype.

Types cannot have default implementations; only object representations can have methods attached. In other languages, such as Axiom (formerly Scratchpad II) [Watt et al., Jenks & Sutor 92], default implementations can be stored with the type (called the category in Axiom). However, in Axiom method lookup rules are complicated by the possibility of methods being inherited both from superclasses and from categories, i.e., along both inheritance and subtyping links. Cecil's inheritance rules are simplified by only searching the inheritance graph. We expect that most type-like entities will actually be declared using the object form so that there is a corresponding representation to hold any default method implementations.