sydlar / LarsPipes
About LarsPipes
For the moment, this is only an outline of the idea behind this project
Basic idea
What if #collect: and #select: were binary operators? Instead of
array collect: firstBlock) select: secondBlock) collect: thirdBlock,
we could then write
array |> firstBlock |? secondBlock |> third block
I believe that it will be practical to introduce binary operators |> and |? (the collect- and select-operator, respectively), such that
aCollection |> aBlockgives a stream consisting of the elements inanCollectiontransformed byaBlock.aStream |> aBlockgives in a similar way a stream.aStream |> aCollectionfills the collection with the elements of the stream.
In a similar way, it could be practical to handle individual objects as well as undefined objects with the same operator:
nil |> aBlockgivesnil(or maybe better an empty stream?).anObject |> aBlcokis synonymous withaBlock value: anObject(or maybe better: an one element stream?)
When it comes to the #select: -operator |? one should of course make similar definitions.
Concatenation of blocks
It would be practical to be able to concatenate blocks, and make pipes that can be used in different contexts: firstBlock |> secondBlock should give an instance of the class Pipe, defined in such a way that
`
aCollection |> (firstBlock |> secondBlock)
is equivalent to
aCollection |> firstBlock | secondBlock.
With a similar definition of the #select:-operator |?, one could make general filter-and-transform-objects as
getMaxInMediumSizedSamples := [ :each | each contents ]
|? [ :contents | contents size > 50 ]
|? [ :contents | contents size < 100]
|> [ :contents | contents max ]
Once getMaxInMediumSizedSamples is defined, one could use it in various contexts.
Lazy evaluation
When we define the operators |> and |? in such a way that they always produce streams, we get a nice feature for free, namely that nothing is evaluated before we ask for it, for instance
(aCollection collect: aBlock) detect: anotherBlock
immediately calls aBlock on all the element of the collection, and then uses detect. On the other hand,
(aCollection |> aBlock |? anotherBlock) next
only evaluates aBlock until the first element where anotherBlock returns true.
Collectors
We should also define collectors, i.e. objects that can collect the data form a stream, so that we for instance could write
(1 to: 10) |> [ :x | 2*x -1 ] |> Collector sum "Gives the sum"
(1 to: 10) |> [ :x | 2*x -1 ] |> Collector product "Gives the product"
(1 to: 10) |> [ :x | 2*x -1 ] |> Collector collect "Collects object in OrderedCollection"
(1 to: 10) |> [ :x | 2*x -1 ] |> Collector inject: anObject into: aBlock. "Similar to #inject:into:"
