So, inspired by this post on SO:

http://stackoverflow.com/questions/10942607/clojure-multi-maps

I've been trying to write some multimap functions, in a transient
version:

https://gist.github.com/anonymous/5660467

This was my first experience with transients, and it's been
problematic.  First problem: transients do not support or preserve
metadata, or so it seems.  I wanted my multimaps to function also as
regular maps until the multi- functionality is needed, so I needed a
way to distinguish "multi" entries from regular ones.  At first blush,
you'd just test to see if the entry is a set; but if you think about
it, you might want to make a regular map have set entries too.  No
problem, that's what metadata's for, right?  But of course this code
doesn't work:

(defn plural? [item]
  (get (meta item) :multi))

(defn pluralize! [item]
  (if (plural? item)
    item
    (transient (with-meta (set (list item)) {:multi true}))))

Since transients do not preserve metadata.

Is this an oversight in Clojure, or something that's intentionally
missing?  The following thread throws a little light on the matter but
is not conclusive (and I couldn't find anything more recent):

https://groups.google.com/group/clojure-dev/browse_thread/thread/acb8e6c1ace4613f/0bd110fd226fe547

In the meantime, how would I best accomplish what I am trying to do
with this use of metadata?

And here's still another issue:

(defn persist-all! [mmap]
  (let [persisted-map (persistent! mmap)
        mkeys (keys persisted-map)]
    (loop [item (first mkeys)
           restof (rest mkeys)
           wmap (transient persisted-map)]
.......

You can see here that in order to get the keys from the transient
multimap, I have to persist it first (since you can't seq on
transients, and calling keys requires seq-ability); but then to
persist all the sets, I re-convert the persisted transient multimap to
a transient (since I'm about to do a bunch of changes on the multimap
at once, which would seem to be what transients are for in the first
place).  That seems redundant, but I haven't found any way around it:
I don't see how to get the keys otherwise, and once I've called
persist! I can't re-use the underlying transient.

I'm sure all these problems are eminently solvable by approaching the
problem in a different way; but I thought this was a good opportunity
to seed some discussion about using transients (and metadata).

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to