IMHO, this is one of the coolest aspects of Clojure: the data structures were designed to be immutable as efficiently as possible. This allows for some of the most critical aspects of the language to function. If you're whole program passes around values that are immutable, you don't ever have to worry about which part of the code owns what. Rust is such a different language but the borrow-checker is solving a nearly identical problem: who owns this memory and who is allowed to change it? In Rust, one owner ever gets to write to a piece of memory and you can move that around. It catches lots of bugs and is extremely efficient, but it is definitely a difficult aspect of the language to master. Clojure just says everyone gets to read and share everything, because every mutation is a copy. One piece of your codebase can never stomp on or free some memory that another part is using. Big tradeoffs with garbage collection but geeze does it make reasoning about Clojure programs SO much easier. And the cornerstone of that idea is fast, immutable data structures by default. Maps are implemented similarly in that they are fast to make mutated copies with structural sharing to save memory.
I still don’t understand why they’re referred to as persistent vectors rather than immutable vectors, but I digress.
You wanted 2+1 to yield 3, but instead you get a runtime exception telling you that 2 can't be changed.
I believe that immutable just means, well, immutable, but persistent means that updates are achieved via structural sharing, so they’re efficient.
if you think immutable updates are O(n) in 2026, you're so far behind the curve it's laughable
it's crazy how many ppl i interview just stop thinking and insist you can't do better than O(n)
haskell too had them (IntMap honestly works fine in that use case)