Re: Idiomatic way to return a single value from an async function

2014-11-11 Thread Daniel Kersten
You could do both:

Make the channel optional. If it's provided, use that and return it. If
it's not provided, create a new one and use and return that.

This way the caller gets to decide which they wish to use based on who the
owner of the channel should be or if the channel should be reused elsewhere.

For example, for a once-off call, creating s new channel may make more
sense but if the function is called frequently it might make more sense to
reuse one channel, especially if this channel is used with other plumbing
like pub/sub or mult which you would otherwise need to set up every time.

On Mon, 10 Nov 2014 17:42 Mike Haney txmikes...@gmail.com wrote:

 Eric Normand has an interesting article on this here:
 http://www.lispcast.com/core-async-code-style

 --
 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.


-- 
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.


Re: Idiomatic way to return a single value from an async function

2014-11-11 Thread László Török
+1, this is mostly what we resort to.

(defn some-async-func [param-a param-b  [out-chan]]
  (let [ch (or out-chan (chan)]
 ...
  )

2014-11-11 8:53 GMT+00:00 Daniel Kersten dkers...@gmail.com:

 You could do both:

 Make the channel optional. If it's provided, use that and return it. If
 it's not provided, create a new one and use and return that.

 This way the caller gets to decide which they wish to use based on who the
 owner of the channel should be or if the channel should be reused elsewhere.

 For example, for a once-off call, creating s new channel may make more
 sense but if the function is called frequently it might make more sense to
 reuse one channel, especially if this channel is used with other plumbing
 like pub/sub or mult which you would otherwise need to set up every time.


 On Mon, 10 Nov 2014 17:42 Mike Haney txmikes...@gmail.com wrote:

 Eric Normand has an interesting article on this here:
 http://www.lispcast.com/core-async-code-style

 --
 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.

  --
 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.




-- 
László Török
Checkout justonemorepoint.com - Know your true value

-- 
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.


Re: Idiomatic way to return a single value from an async function

2014-11-11 Thread Thomas Heller
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.


Re: Idiomatic way to return a single value from an async function

2014-11-11 Thread Stuart Sierra
Similarly, but I would be explicit about the different arities, to avoid 
the intermediate sequence created by [arg  [option]] and to get errors if 
there are too many arguments.

(defn foo
  ([input] (foo input (chan 1))
  ([input ch]
 ... do something and put to ch ...))

If your function can produce multiple outputs, you can `close!` the channel 
to signal it is finished, which is what `pipeline-async` expects.

–S

-- 
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.


Idiomatic way to return a single value from an async function

2014-11-10 Thread Alexander Kiel
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.


Idiomatic way to return a single value from an async function

2014-11-10 Thread Mike Haney
Eric Normand has an interesting article on this here: 
http://www.lispcast.com/core-async-code-style

-- 
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.