All of rusts persistent immutable datastructure libraries like im make use of this for drastically more efficient operations without loss in capability or programming style.
I used the same principle for my rust re-imagination of datascript [1], and the borrow checker together with some merkle dag magic allows for some really interesting optimisations, like set operations with almost no additional overhead.
Which allows me to do stuff like not have insert be the primary way you get data into a database, you simply create database fragments and union them:
let herbert = ufoid();
let dune = ufoid();
let mut library = TribleSet::new();
library += entity! { &herbert @
literature::firstname: "Frank",
literature::lastname: "Herbert",
};
library += entity! { &dune @
literature::title: "Dune",
literature::author: &herbert,
literature::quote: ws.put(
"I must not fear. Fear is the mind-killer."
),
};
ws.commit(library, "import dune");
The entity! macro itself just creates a TribleSet and += is just union.In Clojure this would have been too expensive because you would have to make a copy of the tries every time, and not be able to reuse the trie nodes due to borrow checking their unique ownership.
And thank you for highlighting the conceptual link to Rust's borrow checker. Clojure and Rust are far and away my two favorite languages and this largely articulates why: they both have language-level constructs to completely solve the data ownership problem. Not just "here's some tools to optionally solve it, good luck" but truly, fully solve it. Full stop.
Almost every other language leaves ownership enforcement up to the developer. Clojure and Rust take entirely different approaches to virtually everything, but they converge on this one point and it's a crucial one. Types, syntax, compilation models, garbage collection, etc. are all secondary concerns to managed data ownership IMO.