Types in the Astarte Abstract Machine


Species and parameterized species

The species and parameterized species supported directly by the abstract machine are as follows. Others can be created using instructions that create new species.

() () is the unit type, having only one member. That sole member is also called () here.
Natural A nonnegative integer, arbitrarily large.
Integer An integer (possibly negative), arbitrarily large.
Rational A rational number, stored as the ratio of two integers.
Real A real number, stored approximately.
Char A character. Currently, only the Ascii alphabet is provided, but future versions will allow Unicode.
Boolean True and false.
Symbol A symbol (given by a name).
UnknownKeyType Protected unknowns have keys that are required for binding them. The keys have type UnknownKeyType.
ASpecies A species, when it is used as a value, has species ASpecies.
AFamily A parameterized species, when it is used as a value, has species AFamily.
ExceptionSpecies An exception is a data item that is associated with a failure indicating the reason for the failure. An exception has species ExceptionSpecies.
ExceptionSetSpecies The values of species ExceptionSetSpecies are sets of exceptions.
List List is a parameterized species (or species constructor) that constructs a list species. An item of species List(T) is a sequence of zero or more things of the same species. (Parameterized species List is covariant and conforming. See below for the meaning of this.)
Optional Optional is a parameterized species that adds a null value to an existing species. An item of species Optional(T) is either a special null value (represented by the integer 0) or is a tagged value (X:1) where X has species T. (Parameterized species Optional is covariant and conforming. See below for the meaning of this.)
Box Box is a parameterized species that constructs a box species. An item of species Box(T) is a variable that can either be empty (having no content) or can have a content that is an item of species T. The content can be changed as the program runs. (Parameterized species Box is covariant and nonconforming. See below for the meaning of this.)
SysOutfile SysOutfile is a species of files that have been opened for output. (Files that are open for input are handled by a different mechanism.)
Socket Socket is a species of sockets that can be used for communication between processes or between machines. Currently, only client sockets are supported, but server sockets will be added later.


Genera and parameterized Genera

The abstract machine also supports a concept of an abstract data type that is called a genus. You can think of a genus in more than one way. You can think of it as an abstract data type standing for a set of capabilities. You can, if you prefer, imagine it to be a set of species that have those capabilities. There is also a notion of a parameterized genus, which is a parameterized abstract data type, or a set of parameterized species.

Species and genera a relation called the genus hierarchy that is similar to the subclass relation in an object-oriented language. If genus B lies beneath genus A, (written B <= A) then genus B has all of the capabilities of genus A, and possibly more. For example, Natural <= REAL, and RFIELD <= REAL.

There is a similar hierarchy relating parameterized species and parameterized genera. It is also allowed for a parameterized species or genus F to be beneath a (nonparameterized) genus G. But an unparameterized genus cannot be beneath a parameterized genus.

There are some characteristics of genera and parameterized genera that indicate how the type system makes decisions about relationships among species. Each genus or parameterized genus is either gregarious or shy. Each parameterized genus has some additional characteristics. It is either comforming, noncomforming or top. It is also either covariant or invariant. The meanings of these characteristics are discussed below.

The genera and parameterized genera supported directly by the abstract machine are as follows. Others can be added using instructions that create new genera.

ANY This gregarious genus contains all species. You can think of it as an abstract data type indicating no capabilities.
EQ This gregarious genus contains species that support an equality check.
ORDER This gregarious genus contains species that support order tests (<, etc.)
ENUMERATED This shy genus contains enumerated species that support a collection of operations including selection of the first and last members of the species.
RANKED This shy genus contains species that support a rank operation that converts to a natural number. It is defined to contain only species Natural and all species that are in genus ENUMERATED.
RATIONAL Shy genus RATIONAL contains only species Natural, Integer and Rational. These are the standard numeric species whose values are represented exactly, without roundoff error.
RRING Shy genus RRING contains only species Integer, Rational and Real. These are the standard numeric species that support addition, subtraction, multiplication and division, as well as a few other operations.
RFIELD Shy genus RFIELD contains only species Rational and Real. These are the standard numeric species that support addition, subtraction, multiplication and division, as well as a few other operations.
INTEGER Shy genus INTEGER contains only species Natural and Integer. These are the standard numeric species that support operations typical to integers.
RATRING Shy genus RATRING contains only species Integer and Rational. These are the standard numeric species that support addition, subtraction and multiplication, and whose representation is exact.
INVARIANT Gregarious parameterized genus INVARIANT contains all invariant parameterized genera. It is itself invariant, and top.
COVARIANT Gregarious parameterized genus COVARIANT contains all covariant parameterized genera. It is itself covariant, and top.
INVARIANT_N Gregarious parameterized genus INVARIANT_N contains all parameterized genera that are both invariant and nonconforming. It is itself invariant and nonconforming.
INVARIANT_C Gregarious parameterized genus INVARIANT_C contains all parameterized genera that are both invariant and conforming. It is itself invariant and conforming.
COVARIANT_N Gregarious parameterized genus COVARIANT_N contains all parameterized genera that are both covariant and nonconforming. It is itself covariant and nonconforming.
COVARIANT_C Gregarious parameterized genus COVARIANT_C contains all parameterized genera that are both covariant and conforming. It is itself covariant and conforming.
MAPPABLE Gregarious parameterized genus MAPPABLE contains all covariant parameterized genera that support a map operation. It is itself covariant and top.


Characteristics of species and genera and how the affect relationships

Characteristics of species and genera have the following meanings.

invariant This controls how constructed species relate to one another. If F and G are two invariant parameterized species then F(A) <= G(B) when F <= G and A = B. If one of F and G is invariant and the other is covariant then there is no relationship between F(A) and G(B).
covariant This controls how constructed species relate to one another. If F and G are two covariant parameterized species then F(A) <= G(B) when F <= G and A <= B. If one of F and G is invariant and the other is covariant then there is no relationship between F(A) and G(B).
conforming This controls how constructed species relate to genera. If F is a conforming parameterized species and G is a genus then F(A) <= G just when F <= G and A <= G.
nonconforming This controls how constructed species relate to genera. If F is a nonconforming parameterized species and G is a genus then F(A) <= G just when F <= G.
top A top parameterized species is one whose conforming/nonconforming status is not known. Only secondary parameterized species can be top, and if F is top then the only genus G that can satisfy F <= G is G = ANY.
gregarious A gregarious genus G interacts freely with other genera. Unless there is an explicit indication to the contrary, the species that belong to both G and H are thought of as those that exhibit all characteristics of G and all characteristics of H. The interpreter will create a new genus called G&&H to indicate the genus of all species that belong to both G and H, when necessary. Parameterized genera are handled similarly.
shy A shy genus G does not want to interact with any other shy genus. If G and H are both shy then it is presumed that there do not exist any species that are in both G and H, unless there is explicit evidence to the contrary. A similar rule applies to parameterized genera.


Primary and secondary species, tagging and the global definition table

For each genus there is a corresponding species. For example, REAL is both a genus and a species. A species that corresponds to a genus is called a secondary species. Similarly, there is a secondary parameterized species associated with each parameterized genus.

Species such as Natural and Boolean that do not correspond to genera are called primary species, and parameterized species that do not correspond to parameterized genera are called primary parameterized species.

There is a rule for determining whether a constructed species is primary. A cartesian product species (A, B) is considered to be primary, as is a function species. A constructed species F(A) is primary provided F is a primary parameterized species.

The distinction between primary and secondary species comes in tagging. The WRAP instruction will only attach a primary species to an item. You can understand the reason by thinking of object-oriented computing. Imagine that there is a class called GADGET. This gives you two concepts of a GADGET. One concept of a GADGET is a thing that was created by a constructor for class GADGET, and that you can think of as having a tag on it saying "I am a GADGET." The other concept is of general GADGETS, possibly including specialized kinds of GADGETS. Suppose that WIDGET is a subclass of GADGET, and imagine that you construct an object using a constructor for class WIDGET. The tag will say "I am a WIDGET." But in the second view, it is reasonable to say that this thing is also a GADGET, since every WIDGET is a GADGET. The tag does not change. In fact, the tag is used to determine how an object behaves. A WIDGET will behave like a WIDGET, because of the tag that it carries. As you can see, it is important to distinguish the tags from the more general classes to which objects might belong. This machine solves that by using only primary species as tags. The secondary species represent more general classifications to which objects belong.

For efficiency, primary objects (belonging to primary species) do not carry tags with them. But all objects that belong to secondary species carry tags indicating their primary species. The tag tells, in a sense, which constructor was used to construct them.

The global definition table is used to look up a definition by a (name, species) pair. So when you select a definition, you must indicate its species. If you select a species Natural -> Natural, you get a function that expects an untagged nonnegative integer as its parameter. If you select species REAL -> Natural, you get a function that expects a tagged value as its parameter. What it might choose to do is to examine the tag, and use that tag to get another function. For example, imagine that function resolve has species REAL -> Natural. When resolve is passed parameter (6:Integer) tagged with primary species Integer, it might look up (resolve:Integer -> Natural) in the global definition table, and run that function on (untagged) parameter 6. What the function does is up to that function.


Modifying the hierarchy

A program can modify the hierarchy between @BEGIN-EXTENSION and @END-EXTENSION instructions. When @END-EXTENSION is processed, the entire hierarchy is checked for consistency.

An extension can only introduce new relationships. It cannot change existing relationships that were established at the end of a former extension. You cannot add a species to a genus in one extension if both the species and the genus existed at the end of a former extension, unless that species was already known to belong to that genus. You must be careful how you do extensions. Make all related changes inside an single extension.