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

Reply via email to