Ah, very nice. I had not seen the alt! macro in use but upon close look it is just what I need when using the :default option. My go-loop macro now only requires the single stop channel:

(defmacro go-loop [bindings & body]
  (let [stop (first bindings)]
    `(let [~stop (chan)]
       (go (while (alt! ~stop false :default :keep-going)
             ~@body))
       ~stop)))

Thanks for the tip!


On 7/17/13 2:26 PM, Jonas wrote:
You can also use the alt! macro:

(let [stop (chan)]
  (go (loop []
        (println "Hello World!")
        (alt!
         (timeout 1000) (do (println "I'm done sleeping...")
    (recur))
         stop :ok)))
  (<!! (timeout 10000))
  (>!! stop :now)
  (println "We're done."))


On Wednesday, July 17, 2013 10:31:50 PM UTC+3, 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
    <javascript:>> 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
        <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 clo...@googlegroups.com
        <javascript:>
        Note that posts from new members are moderated - please be
        patient with your first post.
        To unsubscribe from this group, send email to
        clojure+u...@googlegroups.com <javascript:>
        For more options, visit this group at
        http://groups.google.com/group/clojure?hl=en
        <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+u...@googlegroups.com <javascript:>.
        For more options, visit
        https://groups.google.com/groups/opt_out
        <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