next up previous contents index
Next: 3.15 Modules Up: 3 The Slate World Previous: 3.13 Concurrency   Contents   Index


3.14 Types

In coordination with the reserved syntax for type-annotation in block headers, the standard libraries include a collection of representations of primitive TYPES as well as quantifications over those types. The library of types is laid out within the non-delegated namespace Types in the lobby.

3.14.1 Types

The type that any object satisfies: the universal type.
The type that no object satisfies: the empty type.
A parametrized type over another type with a linear ordering, such as Integer. This type is bounded, it has a start and a finish (least and greatest possible member). In general, any Magnitude can be used as a base of a Range type.
The type associated with membership in a specific set of objects.
The type of a single object, as distinct from any other object.
The type of an object and its CLONE FAMILY, the set of objects that are direct copies (clones plus changes to slot values) of it.
The type representing all arrays, as parametrized by an element type and a length.
The type representing code closures of a given (optional) input and output signature.

3.14.2 Operations

Types may be combined in various ways, including union:, intersection:, and extended via derive which preserve type constraints on the derivations.

3.14.3 Type Annotations

Local slot specifiers in a Method header as well as input slot specifiers may have types optionally declared within the header. Within a method declaration expression, the input slots may be redundantly specified in the header as well as in the dispatch expression. However, if this is done, the header's specifier needs to be specified as an input slot and if multiple input slot types are specified, they should be specified in order.

The syntax is similar to that for @-based dispatch notation: follow the slot name with the bang character ``!'' and then a type expression, which may be a primitive or derived type. For example,

[| :foo!Integer bar | bar: (foo raisedTo: 3).  
foo + bar] applyWith: 4.3.
Type annotations don't use primitive expressions: the evaluator doesn't have a library of pre-built types at its disposal. Instead, Type annotation expressions are evaluated within the namespace named Types accessible from the lobby. For this reason, user-defined named types should be installed in some place accessible through the Types path.

3.14.4 Type Inference

Type-inference on syntax trees is driven by calling inferTypes on the Syntax Node in question. This will process type information already annotated to produce derived annotations on related nodes.

Also, there is a facility to extend the type-inference capability per method. To explain, each Type object comes with a rules object slot that is dual to the traits delegate object; rules delegate as the traits do but do not confer to the types their methods. Instead, they are used by the inference system transparently to allow for more intelligent specialization. To wit:

_@((Member of: {True. False}) rules) ifTrue: then@(Block rules) 
   ifFalse: else@(Block rules) 

  then returnType union: else returnType 
is a type-inference extension method for #ifTrue:ifFalse: for any boolean and a pair of blocks, that the return type will be in the union of the blocks' return types.

next up previous contents index
Next: 3.15 Modules Up: 3 The Slate World Previous: 3.13 Concurrency   Contents   Index
Brian Rice 2005-11-21