On Thu, 21 Mar 2019 at 11:00, Robert Hickman <robehick...@gmail.com> wrote:
> I was only making a point for where a non-generator version of > comprehensions could be useful, under the premise "Therefore, a > lazy-evaluating syntax is more powerful, in that it can do everything > an eager-evaluating one can do *and more*.". This implies that it > dosn't have any downsides, whereas performance may be a downside. > Ah, OK, I see where you're coming from. I'm no expert, but I'm not sure how much difference it would actually make. Whether the comprehension is eagerly evaluated internally, or by a call to iterator_to_array, the input will always need to looped over exactly once, with each element being tested against the condition and run through the output mapping. A manual eager implementation (with no output mapping, for simplicity) would look like this: foreach ( $array as $element ) { if ( someCondition ) $newArray[] = $element; } Which is basically equivalent to this: while ( $element = $arrayIterator->next() ) { if ( someCondition ) $newArray[] = $element; } A lazy implementation just moves the if check into the iterator; it might look like this: while ( $element = $filteredArrayIterator->next() ) { if ( someCondition ) $newArray[] = $element; } But $filteredArrayIterator->next() is actually $arrayIterator->next() with a built-in if check, so you could also picture it as doing this: while ( $element = $arrayIterator->nextIf ( someCondition ) ) { $newArray[] = $element; } So the underlying operations are the same, they just happen in different orders. The only real difference I can see is that under a very specific set of circumstances, it could be compiled into a tight loop on the CPU. It would require a JIT to check all of the following held, though: - The input is a plain array, not any other iterable - The condition can be inlined (e.g. not a function call like "if ( checkSomething($x) )") - The output mapping can be inlined (e.g. not a function call like "yield doSomething($x)") Returning a generator by default just requires an extra check in that list: - The expression is contained within iterator_to_array (or whatever syntax shortcut we come up with for that). I might be wrong, though, in which case this would indeed be an argument in favour of having a dedicated array-returning syntax, either alongside or instead of a generator-returning one. Regards, -- Rowan Collins [IMSoP]