Macaulay2 » Documentation
Packages » Macaulay2Doc > The Macaulay2 language > inheritance
next | previous | forward | backward | up | index | toc


Each class has a parent class that can be used as a container for bits of code that apply to a more general class of objects. In this section we show how this mechanism works in detail.

We begin by creating a new type of basic list.
i1 : X = new Type of BasicList

o1 = X

o1 : Type
i2 : parent X

o2 = BasicList

o2 : Type
The parent of X is BasicList, as desired, thus methods applicable to basic lists will also apply also to instances of X. One such method is the method for creating a net from a basic list; here is its code:
i3 : code(net,BasicList)

o3 = -- code for method: net(BasicList)
     --source code:
     net BasicList := x -> horizontalJoin deepSplice (
           net class x, 
           toSequence between(comma,apply(toList x,netn)),
This code is run automatically to display an instance of X, so if we make one, we'll be able to see what it is:
i4 : x = new X from {2,3,4}

o4 = X{2, 3, 4}

o4 : X
Now let's imagine we wish to treat instances of X as vectors, and to negate one by negating its entries. As it happens, no method for this has been installed for basic lists, so trying to negate x results in an error.
i5 : stopIfError = false;
i6 : - x
stdio:6:1:(3): error: no method for prefix operator - applied to object:
--            X{2, 3, 4} (of class X)
We install and test a new method as described in installing methods.
i7 : - X := t -> apply(t,i -> -i);
i8 : - x

o8 = X{-2, -3, -4}

o8 : X
This method will apply automatically to subclasses of X, as we see now.
i9 : Y = new Type of X;
i10 : y = new Y from {4,5,6}

o10 = Y{4, 5, 6}

o10 : Y
i11 : - y

o11 = Y{-4, -5, -6}

o11 : Y
For binary methods, there is an apparent ambiguity in deciding exactly how inheritance will work. Let's illustrate by making a new subclass Z of X.
i12 : Z = new Type of X;
i13 : z = new Z from {7,8,9}

o13 = Z{7, 8, 9}

o13 : Z
Now let's install two methods, either of which might conceivably be applied to evaluate the expression y+z, and see what happens.
i14 : Y + X := (a,b) -> "Y + X";
i15 : X + Z := (a,b) -> "X + Z";
i16 : y + z

o16 = Y + X
The result is the string Y + X. The reason is that after finding that no method applies directly for adding an instance of Y to an instance of Z, the search continues: Z is replaced by its parent X, and so on. (After enough unsuccessful iterations of this, the second type is reset to Z, the first type is replaced by its parent, and the search continues.)

The same search order applies to method functions defined with method.