This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aleph (5)
- # beginners (112)
- # boot (137)
- # cider (10)
- # cljs-dev (36)
- # cljsrn (2)
- # clojure (118)
- # clojure-argentina (1)
- # clojure-berlin (1)
- # clojure-brasil (3)
- # clojure-dev (4)
- # clojure-italy (2)
- # clojure-nl (13)
- # clojure-russia (23)
- # clojure-spec (5)
- # clojure-uk (53)
- # clojurescript (344)
- # clojutre (1)
- # core-async (65)
- # cursive (9)
- # datascript (7)
- # datomic (28)
- # devops (1)
- # emacs (16)
- # events (1)
- # jobs (5)
- # keechma (18)
- # lumo (56)
- # off-topic (7)
- # om (3)
- # onyx (14)
- # protorepl (21)
- # re-frame (3)
- # reagent (20)
- # ring (12)
- # ring-swagger (9)
- # specter (17)
- # unrepl (14)
- # vim (14)
- # yada (22)
I am wondering why core.async does not provide some functionality similar to async/await in C# and JS. go and <! provides a great foundation, but would it not be a good idea to have something that propagates exceptions as well?
Exceptions are always tricky to handle inside core.async. The growing consensus seems to be: catch the exception and pass it through the channel. When possible, if I have a "top level" I might pass a channel just for exceptions around, and the top-level will async/alts! the real result or the exception.
I really don't like it when I see exceptions being passed on the same channel as values
if the go blocks are "long running" internal async services you communicate with via channels, or if go blocks are a calling convention for asynchronous functions
I like to give go blocks the equivalent of the std file descriptors, an in channel, out channel, and error channel (and maybe a shutdown channel)
but, given how often I see exceptions going on the same channel as values, and people writing wrappers for taking from channels that re-throw exceptions and that sort of thing, I suspect the async function style like what C# is the more common idiom
@hiredman I think that's a good plan, and when I'm green-fielding code, that's a great approach. But I also have a lot of legacy core.async code to work on where my options are more limited.
Is there an easier / more canonical way to transform values coming through a single channel than
(async/map a-function [a-chan])?
if you can’t make the channel yourself, you can use pipe and put the transduce on the to channel
peregrine.circle=> (require '[clojure.core.async :as >]) nil peregrine.circle=> (def c (>/chan 4)) #'peregrine.circle/c peregrine.circle=> (def d (>/chan 4 (map #(doto % println)))) #'peregrine.circle/d peregrine.circle=> (def p (>/pipe c d)) #'peregrine.circle/p peregrine.circle=> (= p d) true peregrine.circle=> (>/put! c "hello") true hello peregrine.circle=> (>/put! c "world!") world! true
Yeah, that makes sense.
(async/pipe c (async/chan N (map f))) seems even clumsier than
(async/map f [c]), though.
I guess some APIs let you create a channel and pass it into something which will
put! to it?
Perhaps naively, it seems easiest to me to have a function which returns a channel which will have the data
a function that takes a chan as an arg, and promises to write to it, is much more reasonable to me than a function that returns the channel it will write to
It just reads so much more simply to
(<! (make-an-http-call)) than to
(let [c (chan)] (make-an-http-call c) c)
a good convention is to take the chan as an arg, and also return it - you can also make the arg optional
async/map is deprecated (and I wish that was mentioned in the docs), is there a modern equivalent that handles multiple channels?
Specifically, I've fired several HTTP requests, and I'm now combining them into a single piece of data
so if it’s a promise-chan, you aren’t really mapping per se, but calling a function on the single value once present
Still not used to using transducers with channels: how do I pick a reasonable value for the buffer size?