This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-21
Channels
- # 100-days-of-code (1)
- # announcements (2)
- # beginners (164)
- # cider (23)
- # cljs-dev (30)
- # cljsjs (11)
- # cljsrn (7)
- # clojure (116)
- # clojure-boston (1)
- # clojure-dev (20)
- # clojure-finland (2)
- # clojure-italy (4)
- # clojure-nl (1)
- # clojure-uk (10)
- # clojurescript (39)
- # core-async (19)
- # cursive (43)
- # data-science (2)
- # datomic (24)
- # emacs (10)
- # figwheel-main (20)
- # fulcro (63)
- # hoplon (7)
- # hyperfiddle (7)
- # instaparse (3)
- # kaocha (1)
- # nrepl (3)
- # off-topic (170)
- # onyx (13)
- # other-languages (3)
- # parinfer (13)
- # re-frame (39)
- # reagent (5)
- # reitit (22)
- # ring-swagger (4)
- # shadow-cljs (284)
- # spacemacs (2)
- # sql (27)
- # testing (28)
- # unrepl (2)
Is there a way to get a channel from alts!
without having to create it myself? This pattern of creating a channel, starting a go-loop
which puts onto that channel, and returning that channel doesn't seem very clean.
(let [chan (a/chan)]
(a/go-loop []
(let [[v c] (a/alts! chans)]
(a/>! chan [v c]))
(recur))
chan)
Is there a different pattern for this type of thing? I often make the mistake of not returning the channel and not realizing it for awhile, since the go-loop
returns a channel itself.something you'll see many functions in core.async do is expect the result channel as an argument
an advantage there is that you can provide a new buffering strategy or transducer-enabled channel as a client, without needing to change the function
also it means you need to pass the channel in or the function call won't work :D
Oh, that's a good idea. Thanks 🙂
Or I guess a muli-arity function with an optional buf-or-n
?
that's also an option - but I also like the idea of a function returning the chan from a go-block if it starts one (though there's no rule saying a dog can't play basketball you can't return N channels)
@noisesmith, so you would return a vector with the go-loop
chan and the chan that was provided or created?
I guess so it can be closed by the user if need be?
Then I got nothing :man-shrugging::skin-tone-2:
I like holding on to it, as it's a straightforward way to know if the loop has exited
Is this the only way to execute a function for every value on a channel?
(a/go-loop []
(do-thing (a/<! chan$))
(recur))
Using map
only works if the returned channel is actually read from; how do I force it to evaluate for side-effects?one option is (async/transduce (map do-thing) some-op init chan$)
where some-op is a reducing step - maybe a no-op and init is whatever some-op wants, maybe just nil
Thanks 🙂 I guess it's finally time for me to figure out what transducers are. 😛
they are useful, many parts of Clojure can use them - in common cases you can replace (->> x (map f) (filter g))
with (comp (map f) (filter g))
and get the same behavior with better performance and composibility / first class values as it's a data transform not a syntax
at @dayjob I use a transducer to define the data processing pipeline. In prod that's attached to kafka channels in and out, in tests it can just be hooked up to sequences and we know it's the same thing with the same behavior
this avoids the gotchas of trying to pretend kafka itself provides a seq / consumes a seq