Clojure: Functional way to manipulate Scene Graph

clojure

Solution

Your fundamental process sounds fine. It is flexible in it's current form because you have the option of having a separate thread update the tree for instance and you can implement an "undo" button rather trivially. If after each modification you return both the new tree and the path to the part that changed you could then update only the part that changed in the display. Lots of people have stronger opinions than me on separating "models" and "views" though I suspect that at least some of their wisdom applies here.

Problem

Context I'm dealing with a large, nested, structured document, which shows up on the screen as a scene graph. The user needs to have the ability to modify this document -- which I am currently using functional zippers to implement. Now, currently, I'm redrawing the entire document after every change. However, when the use of a scene graph, I would only need to modify the part that changes. However (without intending to start a flamewar), I'm increasingly starting to feel that this problem is fundamentally a problem about state, not functions. In particular: user actions (up, down, left, right, insert char, delete char) are about manipulating state, not doing calculations there's only one copy of the document at once, it's only hit by one thread, and there's no gain for sharing Current Approach I use functional zippers to store the document and to provide state manipulation functions. Then, I continuously redraw. Solution I suspect might be correct: Store everything in a scene graph, ditch function zippers, and after modification, directly modify the part of the scene graph that changes. Technical Question: Have others dealt with this? Is there a technical, formal name for this problem? (Equiv of "Dining Philosophers" in concurrency?) Is there a well established solution to this problem? Disclaimer This question is a bit soft. I can't paste a code example of minimal broken case since ``` * my code is around 5K LOC * it's not for me to share publicly ``` However, this is a real technical solution, and I hope others can share their answers Thanks!

Original source