Fork me on GitHub
#core-async
<
2015-06-30
>
meow13:06:42

The code from this page: https://github.com/clojure/core.async/wiki/Go-Block-Best-Practices

(defn load-urls 
  "Spools the results of loading several urls onto a channel. 
   does this without creating temporary channels or go blocks"
  [urls out-c]
  (http-call 
    (first urls)
    (fn [response]
      (put! out-c response (fn [_] (load-urls (next urls) out-c))))))

(load-urls urls)

meow13:06:04

Isn't the call to (load-urls urls) missing an argument for the out-c parameter?

roberto13:06:02

the argument is there

roberto13:06:06

[urls out-c]

roberto13:06:25

sorry, I see what you mean

roberto13:06:28

yeah, it is missing

meow14:06:17

Aaaarrrrrggggghhhhhh!!!!!

meow14:06:54

Been pulling my hair out trying to eliminate this error in a go-loop: clojure.lang.ExceptionInfo: Can't recur here at line 182

meow14:06:16

Anyone want to guess the real problem?

meow14:06:15

@roberto: doesn't matter - that's what was so frustrating

roberto14:06:36

I haven’t had that issue

roberto14:06:43

hard to tell without looking at a snippet

meow14:06:21

I hadn't :require-macros the go-loop macro in this module

meow14:06:54

So my code was fine after all, just needed to require go-loop - would have helped if the error message was better

meow14:06:30

I kept thinking I was doing something wrong with the loop or where I was calling recur

meow14:06:32

Lost a good part of my morning, so I won't forget this lesson soon. 😉

meow14:06:13

Was starting to think I was totally clueless on this part of core.async

roberto14:06:54

I have experiences like those everyday

meow16:06:27

does anyone have a good example of using a transducer to extract info from a cljs event object?

meow16:06:07

I'm not sure I'm using the new completing thingie properly

meow16:06:18

This is what I've got so far for feeding the channel:

(defn extract-mouse-info [e]
  {:x (.-clientX e) :y (.-clientY e)})

(defn get-mouse-channel
  ([]
   (get-mouse-channel (sliding-buffer 1)))
  ([buffer]
   (chan buffer (map (completing extract-mouse-info)))))

(defn listen-for! [target event-type channel]
  (events/listen target event-type #(put! channel %))
  channel)

(defn listen-for-mouse-move! [channel]
  (listen-for! js/window EventType.MOUSEMOVE channel))

(defn channel-for-mouse-move!
  ([]
   (listen-for-mouse-move! (get-mouse-channel)))
  ([buffer]
   (listen-for-mouse-move! (get-mouse-channel buffer))))

ghadi16:06:21

completing is a helper to give reducing functions (fn [acc input]) an extra needed arity for use with transduce

ghadi16:06:42

it never needs to be added to transducer arguments

ghadi16:06:00

(map extract-mouse-info) is all you need

samflores16:06:22

I believe completing is intended to be used when creating functions that produce transducers

ghadi16:06:05

samflores: nein... Here's the canonical example of completing:

ghadi16:06:58

if you have a call to reduce that uses transients, you'd do this (reduce conj! (transient []) collection)

ghadi16:06:18

but that leaves you with a transient vector at the end, you need a way of completing the reduction

ghadi16:06:38

so you make the reducing function conj! take an extra arity

ghadi16:06:50

by doing (completing conj! persistent!)

samflores16:06:15

oh, I see. thanks

ghadi16:06:41

which gives you back

(fn ([coll] (persistent! coll))
    ([coll input] (conj! coll input)))

ghadi16:06:50

Adding it all together with transduce, as reduce doesn't know about that extra arity:

(transduce (map whatever) (completing conj! persistent!) (transient []) coll)

ghadi16:06:38

completing is all about the reducing function itself, not the transducer that manipulates the reducing fn

samflores16:06:51

(inc :ghadi)

ghadi16:06:00

:ghadi 😃

meow16:06:17

Sweet! Everything is working. simple_smile

samflores16:06:47

@meow: have you watched the @dnolen webinar on the topic?

meow16:06:35

@samflores: no, I haven't

samflores16:06:12

it’s the last one

meow16:06:37

@samflores: cool, thanks. I'm really digging core.async

meow17:06:10

I'm replacing all my regular event handling code with channels

samflores17:06:46

I went the same way some time ago, but eventually ended up using https://clojars.org/ca.brentvatne/flux

roberto17:06:59

sweet, I just experimented with channels in reagent, but that didn’t work out too well. But I like the idea very much.

meow17:06:43

@samflores: I'll check that out, thanks.