Hi Michal,
well yes, they are applicable to all sorts of collections but only
vectors and maps can be 'r/fold'-ed isn't it? r/fold on a seq will
degrade to reduce won't it? reduced allocation, as you say, is very
important but I'm trying to go the full way and use r/fold as well. I
wouldn't be bothering with this so much - it's just that this particular
problem seems very much like the perfect situation to use r/fold. Both
the search space is massive (chess has very high branching factor) and
there is massive potential for parallel execution since each branch from
the root can essentially be generated/traversed independently...pmap-ing
at the top did very little, using a fixed thread pool did nothing, my
only hope is now r/fold...
Jim
On 21/08/12 16:29, Michał Marczyk wrote:
Actually no, reducers are applicable to all sorts of collections, not
necessarily tree-based. When used with reduce rather than fold, they
perform all their operations in sequence, but with the substantial
benefit of avoiding any intermediate allocations. For example, in
(reduce + 0 (map inc (filter odd? (take 5 (range))))),
the regular Clojure map, filter and take each allocate an intermediate
lazy seq upon which the next layer out operates. Replacing them with
versions from the reducers library results in a single "reducible"
being produced, which can then be asked to reduce itself with the
function + and the initial value 0, doing all processing without any
extra allocations (not even an "outer" sequence; all operations serve
to modify the final numeric return). The result is pretty close to a
Java loop of the following form (simplified somewhat for clarity):
long ret = initial_value;
long took = 0;
for (coll = range(); coll.hasNext();) {
if (took == 5)
break;
else
took += 1;
Long n = (Long) coll.next();
if (!odd(n))
continue;
n += 1;
ret = reducef(ret, n); // reducef would be add here
}
// ret contains the accumulated return value
As for fold, it does not promise any special treatment to leaves of
arbitrary tree structures; rather, it's supposed to partition
collections into blocks, which are then reduced, with the outputs of
this stage later combined by the combining function. Crucially, order
is preserved, so it still makes the most sense to view the input
collection as a sequence / seqable; of course if it is implemented as
a tree (like vectors), then the partitioning can be carried out in a
particularly efficient manner.
Cheers,
Michał
On 21 August 2012 13:04, Jim - FooBar(); <jimpil1...@gmail.com> wrote:
Dear all,
Can anyone redirect me to some 'real code' using reducers? I say 'real-code'
cos I don't consider (r/fold + [1 2 3 4 5]) to be a realistic example of
usage...also, apart from Rich's blogs, I'm having a hard time finding
resources explaining the role of the combining/reducing fns. THe way I
understand it, the entire reducers lib is only applicable (with benefits) to
tree-like structures and so, the reducing fn is the one applied on the
leaves to make them fewer (reduce them) and the combining fn is the one that
essentially propagates the reductions back up the tree (combines them)...
Can anyone confirm this understanding of mine?
Assuming I'm thinking about it the right way, I 'd like to build a map-tree
(nested maps) where the leaves will be reduced using 'max-key' and combined
back up using 'r/cat' , which apparently is a: "high-performance combining
fn that yields the catenation of the reduced values.". Does that make any
sense whatsoever? I'm really struggling to replace (apply max-key #(...)
(:children tree)) with some form of (r/fold r/cat #(max-key (fn [e] ....))
(:children tree))...
I'd love to see some proper usage of reducers so I can understand what is
going on...From all the videos I've watched, I 've understood that the
algorithm I'm implementing (minimax) is an ideal candidate for reducers -
however I've still not managed to tame them...any help/pointers will be
massively appreciated! :-)
Thanks in advance...
Jim
--
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 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