Fork me on GitHub
#core-async
<
2016-02-01
>
genRaiy06:02:43

@jgdavey: thanks - it has some idiomatic code that I can learn from. I think the next trick is to do the windowing. I am thinking that I can have another channel that sends a message every N seconds that can be used to trigger the formation of a new window...

genRaiy08:02:47

BTW I’m generally interested in the kind of event windowing that Flink has but the Flink API is pretty awful for Clojure users and I figure that as @alandipert always says ‘LISP can do it’

codemartin19:02:56

Hi, I'm pretty new to core-async, and super stuck at a problem. I have two channels (`point-chan` & print-chan). The values coming from them two is what I send into my render! function. I want to render every time there is an update to either channel. For instance, when point-chan has an update, I want to call (render! scene (<! point-chan) last-value-from-print-chan), but when print-chan gets an update, I want to (render! scene last-value-from-point-chan (<! print-chan)). My question is can you even 'join' two core-async channels like that? Do I need to keep state in a ref or something?

codemartin19:02:03

Thankful for any input, as my output is blocked 😉

Alex Miller (Clojure team)19:02:58

you can use a loop around alts!! or alts! to wait for either channel to produce a value, then do a channel-specific response

codemartin19:02:58

Thank you @alexmiller for replying. I not really getting your train of thought here. With alts! I can get the value of either channel as soon as they get a value. But I cannot 1: distinguish what channel got a message or 2: 'remember' the 'other' channels last value. The channels will not update at the same time, but I need the value from both of then to pass into render!. How can you feed the output of alts! into a loop like that?

Alex Miller (Clojure team)19:02:44

alts! will return a vector of [value channel], so you can tell which channel is responding

Alex Miller (Clojure team)19:02:28

but you're saying that you need the last value of both channels to pass to render, right?

codemartin19:02:11

Ah, you can of course do (= ch print-chan) (where ch comes from alts!)

Alex Miller (Clojure team)19:02:13

in that case, I would use a loop/recur, where you retain the last value of both on each pass through the loop

Alex Miller (Clojure team)19:02:06

`(loop [last-point nil, last-print nil] (render! scene last-point last-print) (let [[v ch] (alts! [point-chan print-chan]] (if (= ch point-chan) (recur v last-print) (recur last-point v))))

Alex Miller (Clojure team)19:02:10

(loop [last-point nil, last-print nil] (render! scene last-point last-print)  (let [[v ch] (alts! [point-chan print-chan]] (if (= ch point-chan) (recur v last-print) (recur last-point v))))

codemartin19:02:43

Oh I think I get it! Wow that if freaking awesome

Alex Miller (Clojure team)19:02:57

(loop [last-point nil, last-print nil]
  (render! scene last-point last-print)
  (let [[v ch] (alts! [point-chan print-chan]]
    (if (= ch point-chan) (recur v last-print) (recur last-point v))))

Alex Miller (Clojure team)19:02:35

alt! actually lets you build the if into this more cleanly

codemartin19:02:40

Man thank you! That is seriously cool

Alex Miller (Clojure team)19:02:52

but I have a harder time remembering the syntax :)

codemartin19:02:36

Thanks a lot. Writing for-loops all day and doing clojure at home after work, and got stuck on this one. Thank you for pointing me in the right way simple_smile. Will be a good night of hacking

codemartin19:02:14

Gonna try getting it with alt! then as an exercise

Alex Miller (Clojure team)19:02:23

alt is basically alts + conditionally choosing what to do based on which channel fires

Alex Miller (Clojure team)19:02:39

so seems a good match here, but the syntax is a little tricky

codemartin19:02:48

Seems like cond for channels

Alex Miller (Clojure team)20:02:03

well, really cond for alt