Distinguishing between "pull-based" and "push-based" streams in Smalltalk makes no sense, because do: aBlock [self atEnd] whileFalse: [aBlock value: self next]. is in the same <gettableStream> protocol in the ANSI standard as #atEnd and #next, and in most Smalltalk systems it is in Stream. There should never be anything that has #atEnd and #next that doesn't have #do:.
In some Smalltalk systems, Stream and Collection both inherit from a common superclass. In GNU Smalltalk, it's called Iterable, and provides, amongst other things stream1 , stream2 stream allSatisfy: filterBlock stream anySatisfy: filterBlock stream collect: transformBlock stream count: filterBlock stream detect: filterBlock stream detect: filterBlock ifNone: exceptionBlock stream do: actionBlock stream do: actionBlock separatedBy: separatorBlock stream fold: combinerBlock stream inject: initial into: combinerBlock stream noneSatisfy: filterBlock stream reject: filterBlock stream select: filterBlock My Smalltalk library does not do that, but it does have an Enumerable class that's somewhat similar (the distinction is that multiple traversal of a Collection must work, but only single traversal of an Enumerable is required), so readStream asEnumerable reject: filterBlock This makes about 257 Enumerable methods available. Combinators are good, but they should fit in with existing naming conventions. *Arbitrary* overloadings are a bad idea. The pipe "|" allows one to chain iterators - The ">" allows one to create a new collection with data transformed through chained iterators - The ">>" allows one to fill an existing collection with data transformed through chained iterators The vertical bar is used in Smalltalk for "or". It would make sense to have MonadicBlock methods for: 'combinators' | other ^[:x | (self value: x) | (other value: x)] and so on. Smalltalk already has a selector that means "concatenation", namely #, so stream1 , stream2 as in GNU Smalltalk would not be too confusing. Similarly, ">" means "greater than", and it would be deeply confusing to use it for some sort of data construction. We would expect stream1 > stream2 iff the future values of stream1 (as a sequence) are lexicographically greater than the future values of stream2 (as a sequence). Or you could argue for "the relative order of two streams is the relative order of their positions if the have the same underlying Collection or file system object, otherwise undefined".