On Tue, Jan 20, 2009 at 3:06 PM, Stuart Halloway <stuart.hallo...@gmail.com> wrote: > > Hi Hugh, > > I don't see how this would work in general, which is why a I suggested > a special-purpose macro before. Surely you would not want a binding to > force all sequences while that binding is in effect. And if not that, > what would the general strategy be for deciding which sequences to > force, and which not?
OK, well keeping in mind I'm still learning: I agree a macro would do it, approximately this: (defmacro safe-binding [bindings & body] `(binding ~bindings (doall ~...@body))) but why not make "safe" the default? i.e. use "unsafe-binding" if you know it's OK. The doall just forces the result of the function you're calling, right? You said "Surely you would not want a binding to force all sequences while that binding is in effect." No, I would not. You only need to do wrap the body of the binding call in the doall, right? Assuming the general case : callers do not know whether callees have programmed safely for lazy evaluation + binding, and callees do not know whether callers intend to rebind. It would be costly to program every public function as if the caller might rebind some var you are using, so how to write safe code? Caller has to read the documentation and decide to call the function safely (with doall) or not -- that's how it works now. I am suggesting the safe route is for binding to force doall by default; that way if you don't read documentation, your program will work anyway. Again, is the cost of the doall so high, compared to incorrect programs? We're only doing it at the outermost level of the binding. Thanks, Hugh > > Stuart > >> On Tue, Jan 20, 2009 at 12:53 AM, Timothy Pratley >> <timothyprat...@gmail.com> wrote: >>> >>> >>>> How would one go about fixing f1 (or b1)? >>> >>> Depends what you want to achieve... here are two possible 'fixes': >>> >>> ; don't use lazy evaluation >>> (defn f1 [] >>> (doall (map (fn [x] *num* ) [1]))) >>> >>> ; use lazy evaluation, but preserve the binding when the lazy >>> sequence >>> is created >>> (defn f1 [] >>> (let [mynum *num*] >>> (map (fn [x] mynum) [1]))) >>> >>> >> >> Yes, these work. They presume the author of f1 knows that the caller >> is liable to rebind *num*. >> >> Is it always going to be unsafe to use Vars in a lazily evaluated >> function? If so, could the compiler or runtime automate forcing doall >> or let? >> >> I'm understanding better. The caller can also do >> >> (binding [*num* 1024] (doall (f1))) >> >> The caller doesn't necessarily know he's getting a lazy sequence back, >> but this would be a boilerplate pattern you use anytime you use >> binding. Again, could/should Clojure automate doing that? >> >> >> Thanks all for the insights. >> >> Hugh >> >> > > > > > > -- Hugh Winkler, CEO Wellstorm Development 31900 Ranch Road 12 Suite 206 Dripping Springs, TX 78620 USA http://www.wellstorm.com/ +1 512 264 3998 x801 --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---