I've often seen the terms immutable
and const
used interchangeably. However, from my (little) experience, the two differ a lot in the 'contract' they make in code:
Immutable makes the contract that this object will not change, whatsoever (e.g. Python tuples, Java strings).
Const makes the contract that in the scope of this variable it will not be modified (no promise whatsoever about what other threads might do to the object pointed to during this period, e.g. the C/C++ keyword).
Obviously, the two are not equivalent, unless the language is single-threaded (PHP), or has either linear or uniquness typing system (Clean, Mercury, ATS).
First, is my understanding of these two concepts correct?
Second, if there is a difference, why are they almost exclusively used interchangeably?
Best Answer
I’ll speak to C++, where this difference is most relevant.
As you correctly note, immutable means that an object cannot change at all after its creation. This creation can of course occur at runtime, i.e., a
const
object is not necessarily a compile-time constant. In C++, an object is immutable if (1) and either (2) or (3) are met:It has no members declared
mutable
that are mutated byconst
member functionsIt is declared
const
const
member functions do not useconst_cast
to removeconst
qualification in order to mutate any membersHowever, you could also consider access modifiers: if an operation internally mutates an instance, but has no effect on the state of the instance observable through its public interface, then the object is “logically immutable”.
So C++ provides the tools necessary to create immutable objects, but like most everything in C++, the tools are only minimally sufficient, and require diligence to actually use. The state of an instance is not necessarily confined to the instance member variables—because C++ does not provide a way to enforce referential transparency, it can include global or class state as well.
const
also has another function in C++: to qualify references and pointers. Aconst
reference may refer to a non-const
object. It is legal (though not generally necessary or advisable) to useconst_cast
to mutate an object through aconst
reference, if and only if that object is declared non-const
:And of course it’s undefined behaviour to mutate a
const
object: