On Jan 22, 2009, at 11:17 AM, Konrad Hinsen wrote:

>
> On 22.01.2009, at 16:27, Rich Hickey wrote:
>
>>> Now it works - fine. But what happened to the seq that now owns the
>>> stream? Nothing refers to it, so it should be gone.
>>
>> No, the stream must refer to it, in order to keep its promise to
>> return the same seq every time.
>
> OK.
>
>>> Did it perhaps
>>> liberate the stream, so that I can create an iter again? Let's try:
>>>
>>>        (def rand-iter (stream-iter rand-stream))
>>>        (next! rand-iter nil)
>>>        (next! rand-iter nil)
>
>> What you've created an iter on the second time is the seq of the
>> stream. Right now, once you've treated a stream as a seq it will
>> always behave like one. So this second stream-iter call actually
>> creates an iter on a stream on that seq.
>
> Does that mean that calling seq on a stream converts the stream into
> a seq for all practical purposes? That sounds a bit dangerous
> considering that so many operations in Clojure call seq implicitly.
> One can easily have a seq "steal" a stream and not notice it before
> all memory is used up by the seq.
>

Calling seq on a stream yields a seq that will forever own the stream  
- if you think about it a bit, you'll see why that has to be the case.

OTOH, that seq is lazy, so I'm not sure what the memory issue is.

>> I understand this may not be intuitive or clear yet from the docs.  
>> Nor
>> am I set in this being the behavior. The case I am looking towards is
>> this one:
>>
>> (def s (stream (range 10)))
>> (if (seq s)
>>  (take 4 (map-stream inc s))
>>
>> A stream is used as a seq and then passed to a stream function.
>> Without this seqed-stream-behaves-as-seq capability, this will fail
>> with Already iterating, and would have to be written:
>>
>> (if (seq s)
>>  (take 4 (map-stream inc (seq s))))
>
> I think the second is in fact clearer. It seems weird in a largely
> functional context to have an enormous side-effect of calling seq on
> a stream.
>

Again, I don't see the enormous side effect. Steams form a safe,  
stateful pipeline, you'll generally only call seq on the end of the  
pipe. If you ask for a seq on a stream you are asking for a (lazy)  
reification. That reification and ownership is what makes the pipeline  
safe.

I am working on seq/stream api unification right now,  and we will see  
how often we'll be calling seq fns yet subsequently using as a stream.  
Many of those places where seq is called will now call stream instead  
(e.g. sequence fn entry points), and there may be a non-generator- 
capturing function for determining eos.

Rich


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