Content deleted Content added
Fgnievinski (talk | contribs) No edit summary |
Tags: Mobile edit Mobile web edit |
||
(11 intermediate revisions by 9 users not shown) | |||
Line 1:
{{short description|Object whose state cannot be modified after it is created}}
{{Redirect2|Immutable|Immutability|the Christian doctrine|Immutability (theology)|the album|Immutable (album)|the crypto gaming company|Immutable Pty Ltd}}
In [[object-oriented computer programming|object-oriented]] (OO) and [[Functional programming|functional]] programming, an '''immutable object''' (unchangeable<ref>{{cite web|url=http://www.oxfordlearnersdictionaries.com/definition/english/immutable|title=immutable adjective - Definition, pictures, pronunciation and usage notes - Oxford Advanced Learner's Dictionary at OxfordLearnersDictionaries.com|website=www.oxfordlearnersdictionaries.com}}</ref> object) is an [[object (computer science)|object]] whose [[State (computer science)|state]] cannot be modified after it is created.<ref name=Goetz>Goetz et al. ''Java Concurrency in Practice''. Addison Wesley Professional, 2006, Section 3.4. Immutability</ref> This is in contrast to a '''mutable object''' (changeable object), which can be modified after it is created.
YES, THIS IS SPELLED CORRECTLY. IT'S *NOT* "memo*r*ization". READ THE LINKED ARTICLE.
-->{{Not a typo|[[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
== Concepts ==
Line 38:
=== Interning ===
The practice of always using references in place of copies of equal objects is known as ''[[intern (computer science)|interning]]''. If interning is used, two objects are considered equal [[if and only if]] their references, typically represented as pointers or integers, are equal. Some languages do this automatically: for example, [[Python (programming language)|Python]] automatically [[String intern pool|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 ===
Line 44:
=== Violating immutability ===
Immutability does not imply that the object as stored in the computer's [[Computer storage|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 (programming language)|C]] or [[C++]]).
== Language-specific details ==
Line 76:
By enforcing all the fields as immutable, you obtain an immutable type.
<syntaxhighlight lang="
class AnImmutableType
{
Line 89:
}
}
</syntaxhighlight>
C# have records which are immutable.<ref>{{cite web |title=Use record types - C# tutorial - C# |url=https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/records |website=learn.microsoft.com |access-date=23 February 2024 |language=en-us |date=14 November 2023}}</ref><ref>{{cite web |title=Records - C# reference - C# |url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record |website=learn.microsoft.com |access-date=23 February 2024 |language=en-us |date=25 May 2023}}</ref>
<syntaxhighlight lang="csharp">
record Person(string FirstName, string LastName);
</syntaxhighlight>
=== C++ ===
In C++, a [[const-correctness|const-correct]] implementation of <code>
<syntaxhighlight lang="cpp">
class
public:▼
items{items} {}
std::vector<
}▼
const std::vector<Item>& items() const {
}
double computeTotalCost() const {
▲ private:
return std::ranges::accumulate(
▲ std::vector<Item> items_;
items | std::views::transform([](const Merchandise& m) -> double { return m.getPrice(); }), 0.0
);
}
};
</syntaxhighlight>
Line 114 ⟶ 128:
<syntaxhighlight lang="cpp">
class
public:▼
explicit Cart(std::vector<Merchandise> items): items{items} {}
const std::vector<
return ▲ return *total_cost_;
}
int
totalCost = std::ranges::accumulate(
items | std::views::transform([](const Merchandise& m) -> double { return m.getPrice(); }), 0.0
);
}
}
▲ return total_cost;
▲ }
▲ private:
▲ mutable std::optional<int> total_cost_;
};
</syntaxhighlight>
Line 170 ⟶ 181:
A function of type <code>const(S) function(const(T))</code> returns <code>const(S)</code> typed values for mutable, const and immutable arguments. In contrast, a function of type <code>inout(S) function(inout(T))</code> returns <code>S</code> for mutable <code>T</code> arguments, <code>const(S)</code> for <code>const(T)</code> values, and <code>immutable(S)</code> for <code>immutable(T)</code> values.
Casting immutable values to mutable inflicts undefined behavior upon change, even if the original value comes from a mutable origin. Casting mutable values to immutable can be legal when there remain no mutable references afterward. "An expression may be converted from mutable (...) to immutable if the expression is unique and all expressions it transitively refers to are either unique or immutable."<ref name="d_spec_const"/> If the [[compiler]] cannot prove uniqueness, the casting can be done explicitly and it is up to the programmer to ensure that no mutable references exist.
The type <code>string</code> is an alias for <code>immutable(char)[]</code>, i.e. a typed slice of memory of immutable characters.<ref>[https://dlang.org/spec/arrays.html#strings D Language Specification § 12.16] (The terms ''array'' and ''slice'' are used interchangeably.)</ref> Making substrings is cheap, as it just copies and modifies a pointer and a length filed, and safe, as the underlying data cannot be changed. Objects of type <code>const(char)[]</code> can refer to strings, but also to mutable buffers.
Line 336 ⟶ 347:
}
1;
</syntaxhighlight>
=== PHP ===
In [[PHP]] have readonly properties since version 8.1 and readonly classes since version 8.2.<ref>https://www.php.net/releases/8.1/en.php#readonly_properties</ref><ref>https://www.php.net/releases/8.2/en.php#readonly_classes</ref>
<syntaxhighlight lang="php">
readonly class BlogData
{
public string $title;
public Status $status;
public function __construct(string $title, Status $status)
{
$this->title = $title;
$this->status = $status;
}
}
</syntaxhighlight>
=== Python ===
In [[Python (programming language)|Python]], some built-in types (numbers,
<syntaxhighlight lang="python">
Line 345 ⟶ 374:
"""An immutable class with two attributes 'x' and 'y'."""
__slots__ = [
def __setattr__(self, *args):
Line 355 ⟶ 384:
# We can no longer use self.value = value to store the instance data
# so we must explicitly call the superclass
super().__setattr__(
super().__setattr__(
</syntaxhighlight>
Line 365 ⟶ 394:
import collections
Point = collections.namedtuple(
# the following creates a similar namedtuple to the above
Line 460 ⟶ 489:
{{Wiktionary|mutable}}
* [https://www.codeproject.com/Articles/1043301/Immutable-objects-in-Csharp Immutable objects in C#] using 3 simple steps.
* Article [https://web.archive.org/web/20101020235317/http://www.ibm.com/developerworks/java/library/j-jtp02183.html Java theory and practice: To mutate or not to mutate?] by [[Brian Goetz]], from
* [http://www.javapractices.com/Topic29.cjp Immutable objects] from JavaPractices.com
* [http://c2.com/cgi/wiki?ImmutableObject Immutable objects] from [[Portland Pattern Repository]]
|