Earlier in this chapter, we discussed the virtues of immutability and the pitfalls of mutability. However, even though unguarded mutability is fundamentally unsafe, it also has very good single-threaded performance. Now, what if there was a way to restrict the mutable operation in a local context in order to provide safety guarantees? That would be equivalent to combining the performance advantage and local safety guarantees. This can be done with the abstraction called transients, which is provided by Clojure.
First, let us verify that it is safe:
user=> (let [t (transient [:a])] @(future (conj! t :b))) IllegalAccessError Transient used by non-owner thread clojure.lang.PersistentVector$TransientVector.ensureEditable (PersistentVector.java:463)
As we can see, a transient created in one thread cannot be accessed by another:
user=> (let [t (transient [:a])] (seq t)) IllegalArgumentException Don't know how to create ISeq from: clojure.lang.PersistentVector$TransientVector ...