When a type is used to represent a mathematical object, then immutability is desirable, in order to make the strict equality operator work on it. For example, a module M is a type, with its elements are its instances, but we would like to be able to compare two modules quickly, and form sets of modules. This is possible, because we have implemented modules as immutable types, and we have put the methods for adding and subtracting elements of M into the class Vector.
i1 : F = ZZ^3 3 o1 = ZZ o1 : ZZ-module, free |
i2 : class F o2 = Module o2 : Type |
i3 : parent class F o3 = ImmutableType o3 : Type |
i4 : showStructure class F o4 = Thing : HashTable : ImmutableType : Module o4 : Descent |
i5 : showStructure F o5 = Thing : BasicList : Vector : F o5 : Descent |
i6 : v = F_0 + 3*F_2 o6 = | 1 | | 0 | | 3 | 3 o6 : ZZ |
i7 : F === ZZ^3 o7 = true |
i8 : set (ZZ^3, ZZ^2, ZZ^3) 2 3 o8 = set {ZZ , ZZ } o8 : Set |
i9 : peek F o9 = Module of Vector{cache => CacheTable{...3...} } numgens => 3 RawFreeModule => free(rank 3 degrees = {1, 1, 1}) ring => ZZ |
i10 : ZZ^3_0 + ZZ^3_2 o10 = | 1 | | 0 | | 1 | 3 o10 : ZZ |
The object ImmutableType is a type, with ancestor classes HashTable < Thing.