Lazy-Freeze: Another Look at Hashing and Immutability
A new technique is presented where objects turn immutable upon first hash calculation. This approach enables convenient mutability up until the object is used as a dict-key or set-item, without compromising on safety beyond that point.
Python's hash-based collections rely on an implicit contract: once an object is used as a dictionary key or added to a set, its hash value (and thereby contents) should never change. Yet Python's design encourages mutable user-defined classes without enforcing immutability when hashing occurs - leading to subtle bugs when objects modify their state after being hashed.
This talk introduces the "Lazy-Freeze" pattern: a technique where objects automatically transition from mutable to immutable upon their first hash calculation. Unlike the traditional approach which requires immutable construction, Lazy-Freeze allows objects to begin their lifecycle with convenient mutability, then seamlessly lock their state when stability becomes critical.
We'll introduce an implementation mainly using Python's hash and setattr magic methods, discuss examples and performance implications, and explore some sharp corners.