This approach works for the simple case but gets cumbersome it a more realistic loop with several timeouts and conditional logic. For example, here is a reduced use case which I am using my go-loop macro I posted earlier:

(let [heads? (fn [] (> (rand) 0.5))
      heads-time-out 10000
      loop-time-out 100]
  (go-loop [stop-timeout]
           (if (heads?)
             (do
               (println "HEADS! I'm doing some stuff...")
               (sleep heads-time-out stop-timeout)
               (println "doing some more stuff"))
             (sleep loop-time-out stop-timeout))))

The problem, as I see it, is that with your approach the channel from each alts! needs to propagated to the end of the loop. So, I would either need to restructure the code above to do that or use an atom and have the go-loop/sleep macros take care of it for me.

-Ben




On 7/17/13 1:31 PM, David Nolen wrote:
Why not the following?

(let [stop (chan)]
  (go (loop []
        (println "Hello World!")
        (let [[v c]] (alts! [(timeout 10000) stop])]
          (if (= c stop)
            :done
            (do (println "I'm done sleeping, going to recur now...")
  (recur)))))))


On Wed, Jul 17, 2013 at 2:47 PM, Ben Mabey <b...@benmabey.com <mailto:b...@benmabey.com>> wrote:

    Hi all,
    In a number of places where I'm trying core.async I have run
    across the pattern of having a loop inside a go block with some
    timeouts in the loop body.  Contrived example:

        (go
         (while true
           (println "Hello World!")
           (<! (timeout 10000))
           (println "I'm done sleeping, going to recur now...")))

    In situations like these I almost always want to be able to stop
    the loop and prematurely stop the timeouts.  Using alt! we can
    easily handle the need of stopping the timeout.  Stopping the
    overall loop is easy as well but I can't seem to do it without the
    use of an atom.  Here are some macros I've come up with using a
    channel, an atom, and an additional go block:
    https://gist.github.com/bmabey/6023231

    Is there a better way to do this that doesn't involve an atom? If
    we had a `closed?` fn for channels one could write:

        (let [stop (chan)]
          (go
           (while (not (closed? stop))
             (println "Hello World!")
             (alts! [(timeout 10000) stop])
             (println "I'm done sleeping, going to recur now...")))
          stop)

    This seems ideal and a good use case for adding some sort of
    function to detect termination.  Thoughts?

    Thanks,
    Ben

-- -- 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
    <mailto: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
    <mailto:clojure%2bunsubscr...@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
    <mailto:clojure%2bunsubscr...@googlegroups.com>.
    For more options, visit https://groups.google.com/groups/opt_out.



--
--
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/groups/opt_out.



--
--
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/groups/opt_out.


Reply via email to