Fork me on GitHub
#meander
<
2021-01-05
>
ribelo10:01:06

Is it possible to do such a thing?

(m/rewrite [1 2 3 4]
  [!xs ...]
  (reduce + [(m/cata !xs) ...])
  (m/pred number? ?x) ?x)

noprompt16:01:27

(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

markaddleman16:01:15

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
markaddleman16:01:57

Here, we separate out things that meander is great at (manipulating each unit of data) and the things clojure is great at: reducing

Jimmy Miller18:01:28

One thing we are looking to add in zeta is a notion of reduction. So potentially you could write this much more directly.

👍 6
markaddleman19:01:02

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 case

markaddleman19:01:25

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

markaddleman19:01:39

One more example that is nice to see:

(time (m/rewrite (range 100000000)
          ?xs
          (m/app (partial reduce +) ?xs)))
  "Elapsed time: 591.632803 msecs"

ribelo20:01:53

Reduce was just an example. I wanted to ask if it is possible to use cata inside a clojure function; )

noprompt22:01:46

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.