On Dec 13, 2008, at 2:18 AM, Mark Engelberg wrote:

>
> On Fri, Dec 12, 2008 at 9:28 PM, Rich Hickey <richhic...@gmail.com>  
> wrote:
>> I think it's very important not to conflate different notions of
>> sequences. Clojure's model a very specific abstraction, the Lisp  
>> list,
>> originally implemented as a singly-linked list of cons cells. It is a
>> persistent abstraction, first/second/third/rest etc,
>
> OK, I think I see where you're going with this.  It sounds like you're
> saying that one of the key ideas here is that the first/rest interface
> is meant to guarantee a certain kind of persistence.  If I say (first
> (rest coll)), it should aways give me the same thing.  If you designed
> first/rest to work on uncached sequences, most would work this way,
> but there is certainly no guarantee, depending on the nature of the
> generating function.  Since you want the interface to imply this sort
> of guarantee, you have no choice but to cache anything involving
> first/rest (not including things like "seq"ified vectors which are
> inherently cached).  This makes sense.
>

There are other attributes as well, like the concurrency properties of  
lazy-cons, which guarantees once-only evaluation of first and rest.

> So the piece you're working on is to provide better support for things
> that are determined by their generating functions.  You are
> intentionally avoiding using the terms first/rest for these "streams"
> for the reasons above.  Since streams will be easily convertable to
> seqs, we'll be able to get the best of both words.  We can manipulate
> streams, and eventually when we pass the stream to a function that
> requires seqs, it will do the conversion, and stability will be
> guaranteed.
>
> It sounds like a very promising approach, and I'm looking forward to
> seeing the results.  It seems like ideally, it should be as easy as
> possible to manipulate the streams in stream form, so if you're
> working with a stream source you can go as long as possible without
> converting a stream to seq.  Having map/filter/mapcat/comprehensions
> work fluidly over streams as well as seqs could be hugely beneficial.
>

Yes, those things will be available for streams.

>> That said, I think there is certainly room for a stream/generator
>> model, especially for I/O, but also for more efficient collection
>> processing. Such a thing is explicitly one-pass and ephemeral. It  
>> will
>> not have the interface of first/rest, nor Java's thread-unsafe
>> hasNext/next iterator model (shared by Scala). You can obviously  
>> build
>> seqs from streams/generators, and in my model, with a single
>> definition you will get both a stream and seq version of functions
>> like map and filter, as I showed here:
>> http://groups.google.com/group/clojure/msg/53227004728d6c54
>
> OK, looking back over your sneak preview example, I have a couple
> quick comments/questions.
>
> 1.  You are using stream-seq to convert streams to seqs.  Can't you
> just make the seq function work automatically on streams to produce
> the sequence, just like it does on vectors, sets, etc., rather than
> have a special name for converting streams to sequences?  That way,
> you can pass streams to all the functions that begin with (seq coll)
> and you'll get the desired behavior.

No you can't, for the same reasons you can't for Iterator or  
Enumeration seqs. Again it comes down to abstractions, and the  
abstraction for (seq x) is one on persistent collections. It presumes  
that (seq x) is referentially transparent, which it isn't for  
ephemeral sources - i.e. streams aren't colls. It would become quite  
fragile if people had to adopt call-once-only semantics for seq -  
ephemerality would pollute the world. That said, there are a growing  
number of these ephemeral-source-seq functions which could be folded  
into one multimethod.

Also note that converting a stream to a seq may involve I/O (as may  
any consumption of a stream, and stream->seq will call next!), and  
thus will have different concurrency semantics than (seq coll).

>
> 2.  After you've added streams, what will the range function produce?
> Consider making range produce a stream rather than a sequence.
> (Somewhat relatedly, in Python, range produced a concrete list and
> xrange produced a generated stream.  range was so rarely used that one
> of the breaking changes they made in Python 3.0 was to get rid of the
> list-producing range, and start using the name "range" for the
> generator-variant rather than "xrange").

If you look in the svn you'll see that Range already implements  
Streamable, and so can be used in either context.

>
> 3.  In your sneak-preview filter function, it always produces a seq.
> In the spirit of making it easy to work with streams as long as
> possible without conversion, how about making filter return a stream
> in the case that the input is a stream, rather than having separate
> filter-stream and filter public functions?  Or is it not in the spirit
> of Clojure to have functions overloaded in this way?

I'm still on the fence about overloading by type here. I'm not fond of  
sticking "-stream" on everything either, though any prefix/suffix will  
be short.  What you get back from (map f aseq) and (map f astream)  
would be two very different things, and without declared types you  
won't know from looking at the code what you are dealing with. That's  
tricky. Also, as discussed earlier, when transitioning from streams to  
the easier-to-use seqs there will need to be a once-only explicit  
conversion. There are also issues about being able to partition by  
stream(able)/seq(able) - will nothing be both?

Anyway, these are just details, the design is pretty well along (e.g.  
the stream system will be queue and timeout savvy) and I don't see any  
impediments other than needing to cut a release soon :)

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