Hello,

On Mon, Dec 21, 2009 at 11:09 PM, PM <peter.mccull...@gmail.com> wrote:
> I'm a new Clojure user.  I've been working my way through SICP and the
> videos that accompany it, and I've also read the Clojure book.  I
> already do a lot of work with a music notation library (JMSL) in Java,
> and I'd like to see if I could do some tasks more simply in Clojure.
>
> One of the issues I run into is how to represent a musical score using
> immutable objects.  A naïve representation of a score might look
> something like:
>
> - Score contains measures
> - Measures contain staves
> - Staves contain tracks
> - Tracks contain notes
> - Notes contain articulations, dynamics, and other extras.
>
> I've mocked it up before using structmaps, but I get stuck when it
> comes to doing all this with immutable structures.  Immutability is no
> problem for a system like Lilypond where the score data is fixed when
> the program runs, but in a system where some of these items may be
> changing as the score is edited, how do you handle that?  Returning a
> new note via assoc implies that a track's contents would also change,
> making it a new track, and so on up the chain. (?)

Are you worried about data structure copying? Because I think you
shouldn't be. Clojure's persistent data structure minimize copying,
and besides, even in older languages this kind of update has a
'functional flavor'.

For instance, in K&R's "The C Programming Language", 1st edition,
there is an example about counting words which uses a binary tree to
ensure quick access to a word. So this is C, imperative, with manual
memory management. But what they do is reuse subtrees a lot (If one
has to add a word to a tree, it's either added to the left or the
right subtree, and the unmodified subtree is just reused - this means
that, barring unbalancing of the tree, when modifying a tree with N
elements, they actually only change/rebuild Log2(N) nodes, and the
rest is reused).

The same happens a lot with data structures in functional languages -
the simplest example being consing, which creates a new list from an
old list, but it's all a O(1) operation because the old list is just
reused/linked to.

With nested maps in Clojure it's the same. If you use update-in or
assoc-in to update a note, the score is mostly the same, because most
of the old score is reused (even though it's a 'new one' - which makes
sense). <=== so try using update-in, assoc-in and get-in and maybe
your data structure will be easier to manipulate. Zippers are great
too, as James Sofra suggests.

I hope I managed to describe what you were missing, I probably used
too many words in the attempt :-)

-- 
Miron Brezuleanu

-- 
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