If you want real immutable data structures, not a cheap imitation, check out pyrsistent.
If you want real immutable data structures, not a cheap imitation, check out pyrsistent.
Look up persistent data structures [0]
The main trick is to store everything in a tree with a large branching factor.
The elements are on your leaves. When you want to make an edit you need to create only the nodes from the root to the actual leaf. Then you return the new root. Everything else you can share.
This is a log operation, normally implemented with branch 32.
It works with vectors as well as dicts. Creating a copy is constant, it's immutable can be shared freely (especially on GC'd languages).
Insert/Delete are O(log32(n)) instead of O(n) they'd be with a full copy.
[0] https://en.wikipedia.org/wiki/Persistent_data_structure#Pers...
You can do the same thing with binary trees and other structures. It's more fiddly, and there's definitely places where single-ownership allows mutability "under the hood" for real performance gains, but that's the basic idea.
Functional data structures essentially create a proxy on every write. This can be inefficient if you make writes in batches, and you only need immutability between batches.