I've created a few more examples for Kopi, and one is a going to be a simple particle fountain. Every data structure so far in Kopi is immutable, so updating a bunch of positions and velocities is going to create a new vector every frame.
In C++, it would be something as simple as adding a += operator:
positions += velocities
Just introduce (limited) mutation. Add a set! (index, value) similar to Scheme. That works, but I don't want to get in the habit of using mutation functions. Or maybe only make collections mutable an not variables themselves.
Clojure transients are great for construction and builders, but don't work outside of construction. At least you're not supposed to use them.
Introduce state via co-routines. It is possible to create state by sending messages to co-routines, the same way you can create state in Erlang. But this still doesn't solve mutating a vector.
Variable lifetime / transfer of ownership. If there was no aliasing, there would only be one vector, only shared for reading.
Copy on write for everyone except the "owner". Maybe this is the same as above, meaning data that you store in data structures is not changed from under you. If you ask for it again, it may be different, but it won't change locally.
Look more into Haskell's Data.Vector.Mutable. I'm not exactly sure how these work, but I know they use IO or similar monads to hide some of the mutation.