So I'm trying to implement a lazy-evaluating data type (in PHP, though that shouldn't matter any) where you can queue up actions to take on a set of data. This data can come (theoretically) from any traversable object: arrays, generators, and other iterable objects.
So for instance, given a
$collection object containing a unsorted array of integers, you could call methods on that object like
filter($callback) and it will return a new Collection instance with the action queue of the original collection appended with the called method. No queued actions are executed until the absolute last possible moment, e.g. when the data is actually going to be used for output, reduction to a simple value, and even methods like
find only iterate as much as they need to. This restriction is made easier to implement by the collection (currently) not exposing any sort of index access interface.
The underlying implementation once execution is triggered will try and iterate over the underlying data set as few times as possible by logically grouping the queued operations where possible to avoid creating any intermediate representations of the data as much as possible. So if you have multiple
map() operations set up, then it'll compose those. Filter operations can be grouped in to this single execution loop too, all it means is that when the filter/rejection test function fails then the execution ends for that iteration element.
And this all works, right up until one edge case: sorting. Sorting (unless there's a better idea I'm missing here) requires a separate iteration cycle to begin so that the array can begin. Which I don't mind doing, except in certain cases like where I want only, say, exclusively the first
n elements of the sorted collection. At that point, it seems to me that there's no way to know what those values are without sorting the entire collection. Is there any way to avoid that? Otherwise it's going to be a waste of (most of) the advantages of lazy evaluation, and I'd like to avoid that...