I went through a few iterations with the attempt to convert Dennis's ECS design to entirely immutable data structures. I concluded that a straight port was impossible, but I've got a draft implementation of a more elegant design. Once I have it tested (I think I'll finally bring back mutation testing for this), I'm going to try to port Dennis to it, to make sure I properly understand the ramifications.
The big difference is, Dennis's ECS implementation did not actually have the "system" from "entity component system". It basically got by with a concept I called "Views", which were a way to interact with the "World" structure that contained everything else in a type-safe way. The key difference between "Views" and anything in the new system is that Views were explicitly coupled into the "World". In the new system, they're replaced by "Bundles", which are like "Views" that don't do anything, and "Systems", which couple a "Bundle" to a single action that is restricted in what it can actually do. Basically, the "System" operates on a snapshot of the "World" when the system is started, and it ultimately does two things: return either a new bundle to replace the current entity's bundle, or remove the bundle completely, and return any number of bundles to add to the world. These modifications are not visible to the other runs of the system, so there can be no dependence on order. (Or, there can, but it would have to be a deliberate attempt to work around the library.)
It's possible that I'll want more sophisticated interfaces once I try actually using this, but I think this is expressive enough to handle anything I might want to do, somehow. It should just be a question of convenience.
Anyway, I should get those tests done tomorrow. For now, I sleep.