ReviseAlgo Logo

Functional Programming

Immutability

Immutable data patterns in Python — using tuples, frozensets, NamedTuples, and functional update patterns to avoid mutation bugs.

Interview: Shows understanding of defensive programming and functional design principles.

Last Updated: June 12, 2026 8 min read

Immutable data cannot be changed after creation. Instead of modifying existing objects, you create new ones with the desired changes. This eliminates an entire class of bugs related to shared mutable state and makes code more predictable.

Built-in Immutable Types

  • tuple — immutable sequence, replaces mutable lists
  • frozenset — immutable set, can be used as dict keys
  • str, int, float, bool — all immutable primitives
  • NamedTuple — immutable records with named fields

Functional Update Patterns

  • Instead of modifying, return a new object with changes applied
  • Use dataclasses.replace() for dataclass instances
  • Use {**old_dict, "key": new_value} for dict "updates"
  • Use list + [new_item] instead of list.append()

Deep Immutability

Python tuples are only shallowly immutable — they can contain mutable objects:

  • t = ([1, 2],) — tuple is immutable, but t[0].append(3) works!
  • For true deep immutability, nest only immutable types
  • Use frozenset instead of set, tuple instead of list, NamedTuple for records

Interview Insight

Know the difference between shallow and deep immutability. Be able to explain why tuples can contain mutable objects and how to achieve true immutability with nested immutable types.

Use Cases

Configuration objects — prevent accidental modification of settings

Multi-threaded code — immutable data is inherently thread-safe

Dictionary keys — only immutable types can be dict keys

State management — immutable state makes debugging easier (time-travel debugging)

Function arguments — pass immutable data to prevent unexpected mutations

Common Mistakes

Thinking tuples are deeply immutable — they can contain mutable objects

Using mutable default values in NamedTuple or dataclass fields

Mutating function arguments instead of returning new objects

Not using frozen=True on dataclasses that should be immutable

Confusing _replace() (returns new) with in-place modification