Is it possible to do such a thing?
(m/rewrite [1 2 3 4]
[!xs ...]
(reduce + [(m/cata !xs) ...])
(m/pred number? ?x) ?x)
(me/rewrite [1 2 3 4]
[] 0
[?x] ?x
[?x ?y]
(me/app + ?x ?y)
[?x ?y & ?more]
(me/cata [(me/app + ?x ?y) & ?more]))
;; =>
10
another method, if you don't want to give up on reduce
:
(m/rewrite [1 2 3 4]
[!x ...]
(m/app (partial reduce +) [(m/cata !x) ...])
(m/pred number? ?x) ?x)
Here, we separate out things that meander is great at (manipulating each unit of data) and the things clojure is great at: reducing
One thing we are looking to add in zeta is a notion of reduction. So potentially you could write this much more directly.
Because I needed an excuse to procrastinate, I did a little benchmarking using the reduce example above as inspiration:
(comment
(time (reduce + (range 100000000)))
"Elapsed time: 575.223994 msecs"
(time (m/rewrite (range 100000000)
(m/seqable !x ...)
(m/app (partial reduce +) (m/seqable !x ...))))
"Elapsed time: 4946.887344 msecs"
(time (m/rewrite (range 100000000)
(m/seqable !x ...)
(m/app (partial reduce +) (m/seqable (m/cata !x) ...))
(m/pred number? ?x) ?x))
"Elapsed time: 19892.358578 msecs"
(time (m/rewrite (range 100000000)
(m/pred number? ?x) ?x
(m/seqable !x ...)
(m/app (partial reduce +) (m/seqable (m/cata !x) ...))))
"Elapsed time: 14362.69424 msecs"
)
I was a little surprised by the large improvement just from reordering the clauses between the third and fourth caseHaving said and done this, I want to point out that I don't care much about the runtime performance of meander since the programmer performance improvement is massive
One more example that is nice to see:
(time (m/rewrite (range 100000000)
?xs
(m/app (partial reduce +) ?xs)))
"Elapsed time: 591.632803 msecs"
Reduce was just an example. I wanted to ask if it is possible to use cata
inside a clojure function; )
One thing this reminded me of is that Meander should use loop
/`recur` when possible. I just tried
(?x ?y & ?rest)
(m/cata ((m/app + ?x ?y) & ?rest))
on the above and ran out of memory.