In Macaulay2 the behavior of a function depends heavily on the types of the arguments it's presented with. For example, the expression
x+y means the sum if
x and
y are integers, but it means the union if
x and
y are sets. To implement this in a clean fashion, we store the code for doing things with sets in something called
Set and we store the code for doing things with integers in something called
ZZ. We say that each integer is an
instance of
ZZ, and
ZZ is the
class (or type) of each integer. The function
class provides the class of an object, and the function
instance tells whether a given object is an instance of a given class, or a subclass of it, and so on.
i1 : class 33
o1 = ZZ
o1 : Ring
|
i2 : instance(33,ZZ)
o2 = true
|
i3 : instance(33,String)
o3 = false
|
The corresponding mathematical idea is that
ZZ is the set of all integers.
The class of all classes or types is called
Type.
i4 : instance(ZZ,Type)
o4 = true
|
i5 : instance(33,Type)
o5 = false
|
The class of all objects in the system is
Thing.
i6 : instance(33,Thing)
o6 = true
|
Everything has a class, and every class has a
parent. The parent class represents a broader class of objects, and is used to contain code that applies to the broader class. For example,
ZZ is a ring, and every ring is also a type.
i7 : class ZZ
o7 = Ring
o7 : Type
|
i8 : parent class ZZ
o8 = Type
o8 : Type
|
Types are implemented as hash tables -- it's a versatile way of storing bits of code that are needed in various situations; the keys for the hash table are constructed in a certain way from the function and the types of its arguments whose details the user doesn't need to know.