Fork me on GitHub

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]))
;; =>


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)

👍 9

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.

👍 6

Because I needed an excuse to procrastinate, I did a little benchmarking using the reduce example above as inspiration:

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


Having 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)
          (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.