pic
Personal
Website

5b. Mutable and Immutable Objects

PhD in Economics

Defining Mutability

Objects in programming can be broadly classified into two categories: mutable and immutable. Mutable objects are designed to be flexible, allowing their elements to be modified, appended, or removed at will. A prime example of mutable objects is vectors.

In contrast, immutable objects are inherently unchangeable: they prevent any additions, removals, or modifications of their elements. This immutability effectively locks variables into a read-only state, safeguarding against unintended changes. Additionally, it can potentially lead to performance enhancements. Common examples of immutable objects include tuples, which remain fixed once created.

This section will be relatively brief, focusing solely on the distinctions between mutable and immutable objects. Subsequent sections will expand on their uses and properties.

Remark
A popular package called StaticArrays provides an implementation of immutable vectors. We'll explore this package in the context of high performance, as it greatly speeds up computations that involve small vectors.

Examples of Mutability and Immutability

To illustrate the consequences of immutability, the following examples attempt to modify existing elements of a collection. The examples use vectors as an example of mutability and tuples as an example of immutability. Additionally, we present the case of strings, which is a more nuanced example of immutability. Since strings are essentially sequences of characters, their immutability means that individual characters can’t be altered.

x = [3,4,5]

Output in REPL
julia>
x[1] = 0

julia>
x
3-element Vector{Int64}: 0 4 5

x = (3,4,5)

Output in REPL
julia>
x[1] = 0
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Int64, Int64}, ::Int64, ::Int64)

x = "hello"

Output in REPL
julia>
x[1]
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)

julia>
x[1] = "a"
ERROR: MethodError: no method matching setindex!(::String, ::Int64, ::Int64)

The key characteristic of mutable objects is their ability to modify existing elements. Moreover, mutability also commonly allows for the dynamic addition and removal of elements. In a subsequent section, we'll present various methods for implementing this functionality. For now, we simply demonstrate the concept by using the functions push! and pop!, which respectively add and remove an element at the end of a collection.

x = [3,4]

push!(x, 5)       # add element 5 at the end

Output in REPL
julia>
x
3-element Vector{Int64}: 3 4 5

x = [3,4,5]

pop!(x)           # delete last element

Output in REPL
julia>
x
2-element Vector{Int64}: 3 4

x = (3,4,5)

pop!(x)           # error, just like push!(x, <some element>)

Output in REPL
ERROR: MethodError: no method matching pop!(::Tuple{Int64, Int64, Int64})