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