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.