On 20/03/2019 20:39, Stanislav Malyshev wrote:
Hi!
It's not that you can't make an array into a generator, but you can't make
an eagerly-evaluated expression into a lazily-evaluated one.
Not sure what you mean here.
I mean that, given a syntax that lazily-evaluates something, you can
"fast-forward" the result to make it eagerly-evaluated; given a syntax
that eagerly-evaluates something, you cannot do the opposite. Therefore,
a lazy-evaluating syntax is more powerful, in that it can do everything
an eager-evaluating one can do *and more*.
In this particular case, when you're working with an iterator over a
large file, you probably want a generator. Which is very easy to write
using a functional syntax, and the only thing comprehension syntax does
is switching the parts around a bit and saving you writing a "function"
keyword. I don't think it's a very common case though.
Isn't that true of *every* use of the syntax, though, that "all it does
is switch the parts around a bit"? There's nothing that an array
comprehension can do that can't be done any other way, it's just
short-hand; making it return a generator just extends that short-hand to
more use cases.
Of course, when you need to filter iterators, then you need a different
approach. I do not doubt that. I doubt that filtering iterators is the
most common case in PHP to make the comprehension syntax only support it
- I think the case of array transformation is much more common.
I am not saying that it is "the most common case", and I am not saying
that it should be the only thing supported. I am saying that if we don't
have dedicated syntax for each, one way to support *both* variants is to
make the iterator version the base case, and then have a universal
syntax that switches it to an array.
If we do have syntax for both variants, then clearly both cases are
covered anyway - although I think a short-hand for iterator_to_array
would still have merit elsewhere.
But if we only have one, it should be the iterator version, with a
short-hand for iterator_to_array as a separate language improvement.
I think this would significantly reduce the usability of such construct
- to the point that it's easier to use the existing syntax, thus making
new syntax sugar useless. The whole point of syntax sugar is making
common case easy, and doing what you are suggesting is to make a corner
case (existing, but IMHO much less common) easy and make the user work
to achieve the common case.
I think you're arguing against a straw man here. Yes, the cost of the
extra syntax should be weighed against the benefit of the extra
flexibility. And IF the extra syntax was so verbose that it would be
easier to use the existing syntax, that cost would probably be too high.
But that's not what I was suggesting at all; I was picturing a new
operator, a few characters long, which could turn any iterator into an
array.
Are you really saying that something like this:
$a = [ ... (foreach $x as $y if $y < 2 yield $y) ];
would be so verbose that you'd rather write this:
$a = (function() use ($x) { $a=[]; foreach ( $x as $y ) if ( $y < 2 )
$a[] = $y; return $a; })();
or with the shortest closure syntax I can think of, this:
$a = (() => { $a=[]; foreach ( $x as $y ) if ( $y < 2 ) $a[] = $y;
return $a; })();
By all means let's try to weigh the cost and benefit, but let's not jump
to the conclusion that the cost is nearly infinite and the benefit is
nearly zero.
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php