40

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?

gnat
  • 20,543
  • 29
  • 115
  • 306
K.Steff
  • 4,525
  • 2
  • 33
  • 28

8 Answers8

22

Speaking for Java where the keyword "final" represents "const", consider:

final Person someone = new Person();

This means someone can NEVER refer to another Person object. But, you can still change details of the person being referred. E.g. someone.setMonthlySalary(10000);

But, if someone was an "Immutable" object, one of the following would be true: (a) You would not have a method named setMonthlySalary (b) Calling setMonthlySalary would always throw an exception such as UnsupportedOperationException

21

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:

  1. It has no members declared mutable that are mutated by const member functions

  2. It is declared const

  3. const member functions do not use const_cast to remove const qualification in order to mutate any members

However, 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. A const reference may refer to a non-const object. It is legal (though not generally necessary or advisable) to use const_cast to mutate an object through a const reference, if and only if that object is declared non-const:

int        i = 4;         // Non-const object.
const int* p = &i;        // Pointer to a constant integer.

const_cast<int>(p) = 5; // Legal.

And of course it’s undefined behaviour to mutate a const object:

const int  i = 4;         // const object.
const int* p = &i;        // Pointer to a const integer.

const_cast<int>(p) = 5; // Illegal.

Bretwalda
  • 3
  • 2
Jon Purdy
  • 20,597
12

First, is my understanding of these two concepts correct?

Yes but your second question shows that you don't understand these differences.

Second, if there is a difference, why are they almost exclusively used interchangeably?

const in C++ is only used for access level (it means "read-only"), not for immutability. It imply that the access itself is totally separate from the data. For example you could manipulate some data then expose it through a const reference. The access is read-only, but the data itself, as all the datam is mutable.

const only garantee access limitations, while immutability (like in D for example) imply really no way to change the data at whatever stage of the life of the object.

Now, you can simulate immutability in C++ by making sure some data are not possible to be accessed in any other way than const and make sure it is initialized then not touched anymore. But that's not a strong guarantee as languages like D gives you when you mark your data as immutable. The language make sure it is not possible at all to do any operation modifying that data, while in C++ you are still potentially able to change the data through const casting and mutability if really necessary.

In the end, it is not the same at all as it don't offer at all the same guarantees.

Klaim
  • 14,902
  • 4
  • 51
  • 62
10

Immutable objects are those that does not change state after creating it. For example;

string prefix = "Pre";
string postfix = "Post";
string myComplexStr = prefix + postfix;

In this example myComplexStr object is immutable but not constant because it's value is calculated. And it is immutable because it is a string and has a static length property and cannot change.

Const objects are generally used to identify some real constants whose values are known before compilation like Pi, "USA", "StackOverflow.com", port numbers and so on.

From this perspective Const is different from Immutable objects because their values are not calculated by the program.

But if you are talking about "const" keyword in C++, you can say that "const" is used to create immutable objects.

3

Speaking of JavaScript, the key words const and Object.freeze

const applies to bindings variables. It creates an immutable binding, you cannot assign a new value to it.

Object.freeze works on object values. It makes an object immutable. Namely, you cannot change its properties.

zangw
  • 139
  • 5
2

In C, C++ and related languages, there is also a difference between an object being const and your reference or pointer to the object being a constant reference.

If you try to modify a constant object you get undefined behaviour. (You can try to modify a constant object for example by taking its address, casting the address to a non-const pointer, and then using that non-const pointer to modify the object).

The constant pointer or reference on the other hand just tells the compiler that you cannot use this pointer or reference to modify the object. You can cast the pointer or reference and try to modify the object. If the object itself was constant, bad things will happen. If the object wasn't actually constant, it will change. This may of course confuse users of your code and quite possibly cause bugs.

In C, if you use a string literal like "Hello", the five chars and the trailing zero bytes are actually constant, but you get a non-const pointer. Very bad idea to use that non-const pointer to change the object.

In C, you can have a "const restrict" pointer. That means the object pointed to is temporarily constant. If the object is modified by any means while the "const restrict" pointer is in scope, you get undefined behaviour. This is stronger than a const pointer which only prevents you from changing an object through this pointer.

gnasher729
  • 49,096
-1

In C++ they are the same. Although you can change a const object if you have it's location in memory and OS permission to write to that memory.

-1

Consider an object of a example class as "ex", ex is a variable refering to object of class example Constant : means you cannot change the value of variable ex Immutable : means you cannot edit the object, i.e. you cannot change any of the data inside that object

Consider, Class fruit{ Color and size}mango;

If object mango is immutable you cannot change the colour and size but you can do mango = another_fruit_object While if mango is constant you cannot assign any other value to mango but you can change colour and size.

Hope you understand the example.