Hey,

what is your definition of an async function in Clojure? I imagine 
something something that starts a (go ...), if appropriate you can use the 
result of (go ...) as the result of the function since that is a channel 
that will receive the return value of the go block when it dies.

(defn start-async []
  (go (<! (async/timeout 1000))
      :done))

(let [c (start-async)]
  (prn (<!! c)))

Other than it is highly dependent on the function you are writing. 
Sometimes it will be required to take an external channel, sometimes it 
will be useless. Usually depends on the types of coordination required 
between the different parts. There is no universally correct way.

Just my 2 cents,
/thomas

On Monday, November 10, 2014 5:30:41 PM UTC+1, Alexander Kiel wrote:
>
> Hi,
>
> what is the most idiomatic way to return a single value from an async 
> function in Clojure?
>
> A: return a channel which conveys the result later; also closes the channel
>
> (defn f [x]
>   (let [c (chan)]
>     ; put result onto c and close c later
>     c))
>
> B: take a channel onto which the result is put later; do not close that 
> channel; return nil immediately
>
> (defn f [x c]
>   ; put result onto and close c later
>   nil)
>
> Variant A has the advantage that it needs one function argument less than 
> variant B. It's also better usable in higher order functions like map. 
> Variant A is also more easy to use if you need to create a channel anyway.
>
> Variant A has the disadvantage of creating a new channel each time the 
> async function is called. According my measurements using criterium 
> 0.4.3, clojure 1.6.0 and core.async 0.1.346.0-17112a-alpha, the runtime 
> cost of creating a channel is about 8 times more expensive as creating a 
> single object.
>
> Variant B has the advantage to not create a channel on every call. You can 
> supply the same channel many times to the function. On the other hand, the 
> results of multiple calls to f are not likely to arrive on that single 
> channel in call order. If you have such an ordering requirement, you have 
> to create a single channel for each function call anyway.
>
> Variant B has the disadvantage that it requires one function argument more 
> than variant A. As a consequence, you can't simply map such a function over 
> a list of inputs.
>
> Variant A seems to be the winner. But I ask specially because 
> pipeline-async 
> <https://clojure.github.io/core.async/#clojure.core.async/pipeline-async> 
> uses 
> variant B.
>
> What do you think?
>
> Alex
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to