(And for context, here is Christophe's 'while-let' from 2009):

(defmacro while-let

 "Makes it easy to continue processing an expression as long as it is true"
 [binding & forms]
  `(loop []
     (when-let ~binding
       ~@forms
       (recur))))



On Wed, Mar 5, 2014 at 5:09 AM, Dan Cross <cro...@gmail.com> wrote:

> On Saturday, October 17, 2009 11:42:28 PM UTC-4, mbrodersen wrote:
>
>> It would be great to have while-let in contrib. Then I don't have to
>> maintain let-while myself :-)
>
>
> I'm reviving this ancient thread because of core.async.  This seems like
> just the thing for the common pattern of looping over data received from a
> channel until the channel is closed.
>
> Consider the following snippet of Go code that illustrates a common idiom:
>
> func printints(c chan int) {
>         for v := range c {
>                 fmt.Println(v)
>         }
>         fmt.Println("Channel closed!")
> }
>
> (Note: often this would be called in a go routine by e.g., a closure that
> adds and removes from a wait group or something similar, but I omit that
> here for brevity.)
>
> In particular, notice how the 'range' operator interacts with both the
> channel and the 'for' construct to loop over the values received on the
> channel until the channel is closed.  I'd like to do something similar in
> Clojure, but I don't believe that we have an exact analogue; the closest
> I've been able to come up with are the two:
>
> (loop []
>   (when-let [v (<! c)]
>     (println v)
>     (recur)))
>
> and
>
> (while
>   (when-let [d (<! c)]
>     (println d)
>     d))
>
> These work, but neither strikes me as particularly elegant (in particular,
> the use of 'while' here is ugly).  Speaking of 'while, I also see this in
> some places such as the
>
> (while true (let [v (!< c)] (...)))
>
> However, that won't exit when the channel closes.  Indeed, the loop will
> just set 'v' to 'nil' forever after the channel closes (or at least as long
> as 'true' is 'true').
>
> What I really want is a loop that iterates (or recurses) while something
> is true, like the 'while-let' that was discussed in this thread.  That
> seems to capture the semantics of exactly what I want to do when looping
> over the items placed onto a channel.  In particular:
>
> - It captures the semantics of doing something *while* a binding is true;
> exactly what we want when binding something from a  channel get operation.
> - It encapsulates the side-effect in the binding form.
> - It's simpler and more elegant than the alternatives.
>
> Indeed, the 'loop' above is really the body of the 'while-let' macro that
> Christophe Grand posted back in 2009.
>
> Unfortunately, it doesn't seem to have made it into one of the core
> libraries.  Did it ever make it into contrib?  I don't see it in the "Where
> Did Clojure.Contrib Go" list.  The only references to it that I see are to
> an apparent reimplementation:
>
> https://www.versioneye.com/clojure/while-let:while-let/0.1.0 (which
> ultimately leads to...)
> https://github.com/markmandel/while-let/blob/master/src/while_let/core.clj
>
> I don't like that nearly as much as Christophe's version, but it is worth
> noting that the author specifically mentions core.async as well, thus
> implying that there is wider demand for this sort of thing.  Is it worth
> asking that this be added to e.g. the core library?  Or even to core.async?
>
> Thanks,
>
>         - Dan C.
>
>

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