0

In functional programming, data models are immutable, and updating a data model is done by applying a function on the data model, and getting a new version of the data model in return. I'm wondering how people write efficient viewers/editors for such data models, though (more specifically in Clojure)

A simplified example: suppose that you want to implement a viewer for a huge tree. In the non-functional world, you could have a controller for the Tree, with a function updateNode(Node, Value), which could then notify all observers to tell them that a specific node in the tree has been updated. On the viewer side, you would put all the nodes in a TreeView widget, keep a mapping of Node->WidgetNode, and when you are notified that a Node has changed, you can update just the one corresponding NodeWidget in the tree that needs updating.

The solution described in another Clojure MVC question talks about keeping the model in a ref, and adding a watcher. While this would indeed allow you to get notified of a change in the model, you still wouldn't know which node was updated, and would have to traverse the whole tree, correct?

The best thing I can come up with from the top of my head requires you to in the worst case update all the nodes on the path from root to the changed node (as all these nodes will be different)

What is the standard solution for updating views on immutable data models?

Community
  • 1
  • 1
Remko
  • 823
  • 6
  • 16
  • A traditional FP way of efficiently traversing and updating structures are [zippers](http://en.wikipedia.org/wiki/Zipper_%28data_structure%29). I don't know how much they correspond to MVC stuff, but zippers are used in actual applications for similar problems, most prominently [xmonad](http://donsbot.wordpress.com/2007/06/02/xmonad-a-success-for-pure-functional-data-and-quickcheck/). – phipsgabler Sep 21 '13 at 08:43

1 Answers1

1

I'm not sure how this is a problem that's unique to functional programming. If you kept all of your state in a singly rooted mutable object graph with a notify when it changed, the same issue would exist.

To get around this, you could simply store the current state of model, and some information about what changed for the last edit. You could even keep a history of these things to allow for easy undo/redo because Clojure's persistent data structures make that extremely efficient with their shared underlying state.

That's just one thought on how to attack it. I'm sure there are many more.

I also think it's worth asking, "How efficient does it need to be?" The answer is, "just efficient enough for the circumstances." It might be the the plain map of data will work because you don't really have all that much data to deal with in a given application.

BillRobertson42
  • 12,602
  • 4
  • 40
  • 57