Despite what others have said, I'm going to chime in and say that I
think an immutable hierarchy is going to be awkward for the use case
you describe.

In your example, notes are buried fairly deep in a hierarchy.  Now if
you always tend to make manipulations by starting from the root score
node and working your way down the hierarchy, immutability works just
fine.  But if you want to modify a note that somehow you've stored in
a separate list of notes, or the user has clicked on the note, or some
other kind of interaction where the note is being considered
separately from the rest of the hierarchy, you've got a problem.
update-in and assoc-in are only useful if you know the route from the
root score node to the note.  And that information might not be
readily available.  Similarly, the zipper library is only useful if
you've arrived at a given note through a series of zipper-style
navigations down the hierarchy.  So I really doubt that either of
these proposed solutions will do you much good if you need to
frequently manipulate notes without drilling down to get to them.

I think you have two basic options:

1.  Use refs.  A score/measure/note/etc. are each refs containing the
appropriate struct.  This is basically like using pointers in a
typical language, but you have the advantage of using transactions to
make a bunch of simultaneous updates where other threads will never
see the tree in an intermediate state.

2.  Each struct for score/measure/note also contains a "name" field
which contains a unique name.  Maintain a big map of all names to
structs.  Scores do not directly link to measures, but instead contain
the *names* of the measures.  To drill down from a score to the
measure, you must look up the measure by name in the big map.  To
update a note, you just assoc the note name with the new note object
in the big map.  This method is fully immutable.  Updating a note
without knowing the full route through the hierarchy is easy because
the objects are not directly coupled.  The big map of names to structs
is a persistent object that essentially can give you a snapshot
history of all changes that are made.  The main price you pay is that
drilling down through the hierarchy becomes a bit slower because you
must always look up the names in the map.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to