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.
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 listsfrozenset— immutable set, can be used as dict keysstr,int,float,bool— all immutable primitivesNamedTuple— 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 oflist.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
frozensetinstead of set,tupleinstead 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