Iteration or reduction on a transient map

365 views
Skip to first unread message

nicola...@gmail.com

unread,
May 16, 2012, 10:20:10 AM5/16/12
to clojure
Dear all,

Is there a way to apply a function to all members of a transient map?


Best regards,

Nicolas.

Michał Marczyk

unread,
May 16, 2012, 1:08:03 PM5/16/12
to clo...@googlegroups.com
If you want to reduce the map, there's nothing to be gained from the
map being transient -- just use reduce-kv (or reduce pre-1.4) on the
persistent map.

If you want to map over the entries, again, there's nothing to be
gained from the map being transient. (But if you want to pour the
transformed entries into a map, (into {} ...) will use a transient map
to speed up the process.)

If you want to do something like replacing all values in the
transient, you could take the key set of the persistent map and only
then create the transient and modify it while looping over the keys:

(let [m { ... }]
(reduce (fn [out k] (let [v (m k)] ...))
(transient m)
(.keySet m)))

(Or use loop/recur to do the same.)

Note that if you already hold a transient at the point where you want
to perform this operation, you'll need to use persistent! first and
then make a new transient. You'll also need to use persistent! for
reductions and mapping over the entry seq, since transients don't
support operations of this sort.

Cheers,
Michał
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

nicola...@gmail.com

unread,
May 16, 2012, 1:30:50 PM5/16/12
to clo...@googlegroups.com
So, if I have a transient and want to reduce it and then continue to
use it transiently,
I need to call persistent!, reduce and transient again.

Is there a reason for that?

(The documentation says that read operation are allowed. And it is
actually possible
to write a reduce for a transient vector.)

Michał Marczyk

unread,
May 16, 2012, 2:06:00 PM5/16/12
to clo...@googlegroups.com
Well, I don't know if it's an explicit design goal of transients to
not support these kinds of operations or if noone felt the need for
them strongly enough to implement them.

I believe transients are not meant to be the final solution to the
problems which are currently addressed through their use -- see the
various mentions of pods for hints at an interesting direction in this
design space. This might be relevant in that one might feel less
inclined to work on code which is already meant to be replaced
completely if there's no pressing need to do so.

Issues to think about -- seq would have to deal with the possibility
of the transient changing from under the seq, though that's also true
of arrays, say, so probably not a big deal. Reduce could work fine,
but one should probably enforce that it only happens on the owning
thread (although something like fold could still distribute work among
multiple threads as long as the owning thread called it and blocked
waiting for the result).

NB. calling persistent! then transient again from time to time is
likely not a big deal. The immediate cost is an allocation of the
persistent object followed by two allocations -- of the transient and
of an AtomicReference to the current thread. (There's a small handful
of field reads and assignments in ctors.) Then there's a further cost
of reallocating the editable nodes inside the transient -- just once,
when the node is first modified. If in between reductions you modify
different parts of the transient, that second part of the cost won't
even be there.

Cheers,
M.
Reply all
Reply to author
Forward
0 new messages