This is a good question. As is often the case, the semantic description in the base UML specification is a bit vague. However, Alf is based on Foundational UML (fUML) semantics, and fUML is precise on this point.
The short answer is that data types are, indeed, passed by value, not reference and are immutable. Any apparently mutating operation on a value of a data type actually results in the creation of a new value. For example, consider the following Alf code for the Point data type:
a = new Point(1,1);
b = a;
a.x = 2;
The assignment b = a;
actually copies the point data value. The assignment a.x = 2;
thus has no effect on b
. Indeed, this second assignment is actually equivalent to a = new Point(2, a.y);
. That is, it results in the creation of a new point data value that is then re-assigned to a
.
These semantics are explicitly covered in the Alf and fUML specifications. The definition of data types is covered in subclause 10.4.4 of the Alf spec 1. However, the semantics of assignment per above is in subclause 8.8, where it says, under the description of a simple assignment to a property reference (like a.x
):
If the property reference has a primary expression that is a local
name or parameter name and has a type that is a structured data type,
then the assignment to the property reference effectively assigns a
new data value to that local or parameter name, with the given
property updated.
If you are interested in further details on the semantics of data values, you can find this in the fUML spec 2. The semantics of values are discussed in subclause 8.3.2.1. The key thing is that there is a distinction made between data values and "extensional values". Extensional values exist in the extent of their classifiers at an execution locus independent of their use -- this is the equivalent in fUML of the runtime implementation concept of a "heap".
Extensional values include links, which are instances of associations, and objects, which are instances of classes. Further, there are reference values that are used to refer to objects. It is always references to objects that are passed around, not the object itself -- the object simply exists at the execution locus ("on the heap"). Thus, objects have reference semantics, as opposed to data values, which can be themselves be passed around as values.
There is thus no vagueness on the semantics of data values vs. objects in the fUML spec.