Chapter 8. Immutable Classes

Table of Contents
8.1. Defining Immutable Classes
8.2. Using Immutable Classes

Sather has special support for classes that define immutable objects. Such objects cannot be modified after they have been created, and are said to have value semantics. Many of the basic types such as integers and floating point numbers (the INT and FLT classes) are implemented using immutable classes. This chapter illustrates how immutable classes may be defined, and highlights the peculiarities in their usage that may trip up a beginning user.

At a fundamental level: immutable classes define objects which, once created, never change their value. A variable of an immutable type may only be changed by re-assigning to that variable. When we wish to only modify some portion of an immutable class, we are compelled to reassign the whole object. For experienced C programmers the difference between immutable and reference classes is similar to the difference between structs (immutable types) and pointers to structs (reference types). Because of that difference, reference objects can be referred to from more than one variable (aliased), while immutable objects cannot.

This section illustrates the definition of immutable types using a simple version of the complex number class, CPX. We also describe the benefits of immutable classes and when they should be used. Finally, we close with a description of a how to transparently replace in immutable class by a standard reference class which implements value semantics.

8.1. Defining Immutable Classes

In most ways, defining and using immutable classes is similar to defining and using reference classes. Immutable classes consist of a collection of attributes and functions that can operate on the attributes. Since we have already described reference classes in considerable detail, we will describe immutable classes in terms of their differences from reference classes.

8.1.1. Immutable Class Example

We illustrate the use of immutable classes through the example of the complex class CPX. The version shown here is a much simplified version of the library class. The key point to note is the manner in which attribute values are set in the create routine.
immutable class CPX is
   readonly attr real,imag:FLT;

   create(re,im:FLT):SAME is
      -- Returns a complex number with real and imaginary parts set
      res:SAME;
      res := res.real(re);
      res := res.im(im);
      return res;
   end;

   plus(c:SAME):SAME is
      -- Return a complex number, the sum of 'self' and c'.
      return #SAME(real+c.real,imag+c.imag);
   end;
end; -- immutable class CPX

The complex class may then be used in the following manner.
b:CPX := #(2.0,3.0);
d:CPX := #(4.0,5.0);
c:CPX := b+d;

8.1.2. Creating a new object

Unlike reference classes, instances of an immutable class are not explicitly allocated using the 'new' expression. A variable of an immutable class always has a value associated with it, from the point of declaration. In the example above, the return variable of the create routine ,'res' simply has to be declared.

8.1.3. Initial value of immutable objects

The initial value of an immutable object is defined to have all its fields set to the 'void' value and this is defined to be the 'void' value of the immutable object. Note that this 'void' value means something different than it does for a reference class. It does not mean that the object does not exist, but rather that all its fields have the 'void' value.

Void value of the basic classes:

Class      Initial Value
------------------------
INT        0
CHAR       '\0'
FLT        0.0
FLTD       0.0d
BOOL       false

The initial values for the built-in immutable classes are defined above. These values will return true for the 'void' test.

8.1.4. Attribute access routines

Since an immutable object cannot change its value, what does assigning to an attribute mean? Sather's immutable classes define attribute assignment to create a copy of the original object, with the attribute modified. Thus the attribute declaration 'attr re:FLT ' of the CPX class has an implicit attribute setting routine with the signature:
re(new_re_part:FLT):SAME;

which returns a copy of the original CPX object in which the attribute 're' has the new value 'new_re_value'. Contrast this with a reference class, in which the setting routine would have the signature
re(new_re_part:FLT);

The syntax of the setting routines of immutable classes is a common source of confusion.

8.1.5. Points to note