On Thu, 21 Mar 2019 at 11:00, Robert Hickman <[email protected]> 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]