In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object.
Strings and other concrete objects are typically expressed as immutable objects to improve readability and runtime efficiency in object-oriented programming. Immutable objects are also useful because they are inherently thread-safe. Other benefits are that they are simpler to understand and reason about and offer higher security than mutable objects.
Video Immutable object
Concepts
Immutable variables
In imperative programming, values held in program variables whose content never changes are known as constants to differentiate them from variables that could be altered during execution. Examples include conversion factors from meters to feet, or the value of pi to several decimal places.
Read-only fields may be calculated when the program runs (unlike constants, which are known beforehand), but never change after they are initialized.
Weak vs strong immutability
Sometimes, one talks of certain fields of an object being immutable. This means that there is no way to change those parts of the object state, even though other parts of the object may be changeable (weakly immutable). If all fields are immutable, then the object is immutable. If the whole object cannot be extended by another class, the object is called strongly immutable. This might, for example, help to explicitly enforce certain invariants about certain data in the object staying the same through the lifetime of the object. In some languages, this is done with a keyword (e.g. const
in C++, final
in Java) that designates the field to be immutable. In some languages, it is reversed: in OCaml, fields of an object or record are by default immutable and need to be explicitly marked with mutable
to be so.
References to objects
In most object-oriented languages, objects can be referred to using references. Some examples of such languages are Java, C++, C#, VB.NET, and many scripting languages, such as Perl, Python, and Ruby. In this case, it matters whether the state of an object can vary when objects are shared via references.
Copying objects
If an object is known to be immutable, it can be copied simply by making a copy of a reference to it instead of copying the entire object. Because a reference (typically only the size of a pointer) is usually much smaller than the object itself, this results in memory savings and a potential boost in execution speed.
The reference copying technique is much more difficult to use for mutable objects, because if any user of a reference to a mutable object changes it, all other users of that reference will see the change. If this is not the intended effect, it can be difficult to notify the other users to have them respond correctly. In these situations, defensive copying of the entire object rather than the reference is usually an easy but costly solution. The observer pattern is an alternative technique for handling changes to mutable objects.
Copy-on-write
A technique that blends the advantages of mutable and immutable objects, and is supported directly in almost all modern hardware, is copy-on-write (COW). Using this technique, when a user asks the system to copy an object, it will instead merely create a new reference that still points to the same object. As soon as a user attempts to modify the object through a particular reference, the system makes a real copy, applies the modification to that, and sets the reference to refer to the new copy. The other users are unaffected, because they still refer to the original object. Therefore, under COW, all users appear to have a mutable version of their objects, although in the case that users do not modify their objects, the space-saving and speed advantages of immutable objects are preserved. Copy-on-write is popular in virtual memory systems because it allows them to save memory space while still correctly handling anything an application program might do.
Interning
The practice of always using references in place of copies of equal objects is known as interning. If interning is used, two objects are considered equal if and only if their references, typically represented as integers, are equal. Some languages do this automatically: for example, Python automatically interns short strings. If the algorithm that implements interning is guaranteed to do so in every case that it is possible, then comparing objects for equality is reduced to comparing their pointers - a substantial gain in speed in most applications. (Even if the algorithm is not guaranteed to be comprehensive, there still exists the possibility of a fast path case improvement when the objects are equal and use the same reference.) Interning is generally only useful for immutable objects.
Thread safety
Immutable objects can be useful in multi-threaded applications. Multiple threads can act on data represented by immutable objects without concern of the data being changed by other threads. Immutable objects are therefore considered to be more thread-safe than mutable objects.
Violating immutability
Immutability does not imply that the object as stored in the computer's memory is unwriteable. Rather, immutability is a compile-time construct that indicates what a programmer can do through the normal interface of the object, not necessarily what they can absolutely do (for instance, by circumventing the type system or violating const correctness in C or C++).
Maps Immutable object
Language-specific details
In Python, Java and the .NET Framework, strings are immutable objects. Both Java and the .NET Framework have mutable versions of string. In Java these are StringBuffer
and StringBuilder
(mutable versions of Java String
) and in .NET this is StringBuilder
(mutable version of .Net String
). Python 3 has a mutable string (bytes) variant, named bytearray
.
Additionally, all of the primitive wrapper classes in Java are immutable.
Similar patterns are the Immutable Interface and Immutable Wrapper.
In pure functional programming languages it is not possible to create mutable objects without extending the language (e.g. via a mutable references library or a foreign function interface), so all objects are immutable.
Ada
In Ada, any object is declared either variable (i.e. mutable; typically the implicit default), or constant
(i.e. immutable) via the constant
keyword.
Subprogram parameters are immutable in the in mode, and mutable in the in out and out modes.
C#
In C# you can enforce immutability of the fields of a class with the readonly
statement. By enforcing all the fields to be immutable, you will obtain an immutable type.
C++
In C++, a const-correct implementation of Cart
would allow the user to declare new instances of the class as either const
(immutable) or mutable, as desired, by providing two different versions of the getItems()
method. (Notice that in C++ it is not necessary -- and in fact impossible -- to provide a specialized constructor for const
instances.)
Note that, if there were a field that is a pointer or reference to another object, then it might still be possible to mutate the object pointed to by such a pointer or reference within a const method, without violating const-correctness. It can be argued that in such a case the object is not really immutable.
C++ also provides abstract (as opposed to bitwise) immutability via the mutable
keyword, which allows a member variable to be changed from within a const
method.
Java
A classic example of an immutable object is an instance of the Java String
class
The method toLowerCase()
will not change the data "ABC" that s
contains. Instead, a new String object is instantiated and given the data "abc" during its construction. A reference to this String object is returned by the toLowerCase()
method. To make the String s
contain the data "abc", a different approach is needed.
Now the String s
references a new String object that contains "abc". There is nothing in the syntax of the declaration of the class String that enforces it as immutable; rather, none of the String class's methods ever affect the data that a String object contains, thus making it immutable.
The keyword final
(detailed article) is used in implementing immutable primitive types and object references, but it cannot, by itself, make the objects themselves immutable. See below examples:
Primitive type variables (int
, long
, short
, etc.) can be reassigned after being defined. This can be prevented by using final
.
Reference types cannot be made immutable just by using the final
keyword. final
only prevents reassignment.
Primitive wrappers (Integer
, Long
, Short
, Double
, Float
, Character
, Byte
, Boolean
) are also all immutable. Immutable classes can be implemented by following a few simple guidelines.
Perl
In Perl, one can create an immutable class with the Moo library by simply declaring all the attributes to be read only:
Creating an immutable class used to require two steps: first, creating accessors (either automatically or manually) that prevent modification of object attributes, and secondly, preventing direct modification of the instance data of instances of that class (this was usually stored in a hash reference, and could be locked with Hash::Util's lock_hash function):
Or, with a manually written accessor:
Python
In Python, some built-in types (numbers, booleans, strings, tuples, frozensets) are immutable, but custom classes are generally mutable. To simulate immutability in a class, one should override attribute setting and deletion to raise exceptions:
The standard library helper namedtuple creates simple immutable classes:
is roughly equivalent to the above, plus some tuple-like features.
JavaScript
In JavaScript, some built-in types (numbers, strings) are immutable, but custom objects are generally mutable.
To simulate immutability in an object, one may define properties as read-only (writable: false).
However, the approach above will still allow new properties to be added. Alternatively, one may use Object.freeze to make existing objects immutable.
The use of immutable state has become a rising trend in JavaScript since the introduction of React, which favours Flux-like state management patterns such as Redux.
Racket
Racket substantially diverges from other Scheme implementations by making its core pair type ("cons cells") immutable. Instead, it provides a parallel mutable pair type, via mcons
, mcar
, set-mcar!
etc. In addition, many immutable types are supported, for example, immutable strings and vectors, and these are used extensively. New structs are immutable by default, unless a field is specifically declared mutable, or the whole struct:
The language also supports immutable hash tables, implemented functionally, and immutable dictionaries.
Scala
In Scala, any entity (narrowly, a binding) can be defined as mutable or immutable: in the declaration, one can use val
(value) for immutable entities and var
(variable) for mutable ones. Note that even though an immutable binding can not be reassigned, it may still refer to a mutable object and it is still possible to call mutating methods on that object: the binding is immutable, but the underlying object may be mutable.
For example, the following code snippet:
defines an immutable entity maxValue
(the integer type is inferred at compile-time) and a mutable entity named currentValue
.
By default, collection classes such as List
and Map
are immutable, so update-methods return a new instance rather than mutating an existing one. While this may sound inefficient, the implementation of these classes and their guarantees of immutability mean that the new instance can re-use existing nodes, which, especially in the case of creating copies, is very efficient.
See also
- Clojure
- Erlang
- F#
- Haskell
- Prolog
- Tcl
- Scala
- Mutator method
References
This article contains some material from the Perl Design Patterns Book
External links
- Article Java theory and practice: To mutate or not to mutate? by Brian Goetz, from IBM DeveloperWorks -- saved copy at Internet Archive by Brian Goetz, from IBM DeveloperWorks -- saved copy at Internet Archive
- Immutable objects from JavaPractices.com
- Immutable objects from Portland Pattern Repository
- Objects Should Be Immutable by Yegor Bugayenko
- Immutable.js by Facebook
- Immutable structures in C# opensource project in Codeplex
- Immutable collections in .NET official library by Microsoft (NuGet Package)
Source of article : Wikipedia