Draft RFC: foreach iteration of keys without values

  111774
September 2, 2020 03:15 mike@newclarity.net (Mike Schinkel)
--Apple-Mail=_1009EBD9-A59E-423B-8FB4-C234A4AD6DB6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

This is a new thread for John Bafford's RFC which he mentioned on =
another thread, see below:

https://wiki.php.net/rfc/foreach_void =
<https://wiki.php.net/rfc/foreach_void>=20

> On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: >=20 > Hi Riikka, >=20 >> On Aug 31, 2020, at 14:13, Riikka Kalliom=C3=A4ki = kalliomaki@riimu.net> wrote:
>>=20 >> A common pattern that I've seen that could dearly use PHP internal >> optimization, if possible, would be: >>=20 >> foreach (array_keys($array) as $key) { >> } >=20 > I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch = (https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I =
think) that helps with this, by allowing the following syntax:
>=20 > foreach($iterable as $key =3D> void) { ... } >=20 > This would iterate over the keys of the iterable, and does not = retrieve the values at all.
>=20 > In theory, this should be a general performance win any time one needs = to iterate over only the keys of an iterable, because it does not =
require the use of an O(n) iteration and building of the array that = array_keys() would, plus it works on non-array types (such as generators = or iterators). It also is more performant than foreach($iterable as $key = =3D> $_) {}, because it omits the opcode that instructs the engine to = retrieve the value. (Presumably, a future direction could include using = this request to inform generators or iterators to only return keys, and = not values, which could further improve performance, especially if value = generation is expensive. But that is out of scope for this RFC.)
>=20 > If this is something we'd like for PHP 8.1 and there are no major = objections to the idea, then after 8.0 is released, I can move the RFC =
out of Draft and into Under Discussion, and presuming a vote passes, = I'll update the patch as necessary to work against 8.0. But my time is = limited and I'm not willing to put further time into the code unless an = RFC vote passes.
>=20 > Thoughts anyone?
+1 from me. =20 BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to = update that? -Mike= --Apple-Mail=_1009EBD9-A59E-423B-8FB4-C234A4AD6DB6--
  111776
September 2, 2020 10:48 olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=)
An alternative syntax would be

    foreach($iterable as $key => _) { ... }

Using underscore as a way to signal "I don't care about this value".
Same could be possible with list destructoring, like

    [_, _, $something] = foo();

This syntax comes from OCaml. Possibly other languages, too? Not sure.

2020-09-02 3:15 GMT, Mike Schinkel <mike@newclarity.net>:
> This is a new thread for John Bafford's RFC which he mentioned on another > thread, see below: > > https://wiki.php.net/rfc/foreach_void > <https://wiki.php.net/rfc/foreach_void> > >> On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: >> >> Hi Riikka, >> >>> On Aug 31, 2020, at 14:13, Riikka Kalliomäki >>> kalliomaki@riimu.net> wrote: >>> >>> A common pattern that I've seen that could dearly use PHP internal >>> optimization, if possible, would be: >>> >>> foreach (array_keys($array) as $key) { >>> } >> >> I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch >> (https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I >> think) that helps with this, by allowing the following syntax: >> >> foreach($iterable as $key => void) { ... } >> >> This would iterate over the keys of the iterable, and does not retrieve >> the values at all. >> >> In theory, this should be a general performance win any time one needs to >> iterate over only the keys of an iterable, because it does not require the >> use of an O(n) iteration and building of the array that array_keys() >> would, plus it works on non-array types (such as generators or iterators). >> It also is more performant than foreach($iterable as $key => $_) {}, >> because it omits the opcode that instructs the engine to retrieve the >> value. (Presumably, a future direction could include using this request to >> inform generators or iterators to only return keys, and not values, which >> could further improve performance, especially if value generation is >> expensive. But that is out of scope for this RFC.) >> >> If this is something we'd like for PHP 8.1 and there are no major >> objections to the idea, then after 8.0 is released, I can move the RFC out >> of Draft and into Under Discussion, and presuming a vote passes, I'll >> update the patch as necessary to work against 8.0. But my time is limited >> and I'm not willing to put further time into the code unless an RFC vote >> passes. >> >> Thoughts anyone? > > +1 from me. > > BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to update > that? > > -Mike
  111777
September 2, 2020 11:27 dik.takken@gmail.com (Dik Takken)
On 02-09-2020 12:48, Olle Härstedt wrote:
> An alternative syntax would be > > foreach($iterable as $key => _) { ... } > > Using underscore as a way to signal "I don't care about this value". > Same could be possible with list destructoring, like > > [_, _, $something] = foo(); > > This syntax comes from OCaml. Possibly other languages, too? Not sure.
The underscore is also used for this same purpose in both Python and Javascript. However, it is a normal, valid variable name in those languages. It is not in PHP. I think I would prefer '_' over 'void' because of consistency with other languages. However, we should also consider that: 1. It is currently a valid constant name (BC break) 2. It might be ambiguous in some contexts in which we may want to use it in the future. We should carefully consider other possible use cases like array destructuring. Regards, Dik Takken
  111779
September 2, 2020 13:15 josh@joshbruce.dev (Josh Bruce)
> On Sep 2, 2020, at 6:27 AM, Dik Takken takken@gmail.com> wrote: > > On 02-09-2020 12:48, Olle Härstedt wrote: >> An alternative syntax would be >> >> foreach($iterable as $key => _) { ... } >> >> Using underscore as a way to signal "I don't care about this value". >> Same could be possible with list destructoring, like >> >> [_, _, $something] = foo(); >>
Swift also uses the underscore in places.
>> 1. It is currently a valid constant name (BC break)
I can name a constant an underscore?? Does anyone actually do this?? I guess I’m asking how impactful the break would be considering most magic things start with double underscore and I haven’t seen many people using the single underscore to represent instance variables anymore.
  111780
September 2, 2020 13:35 chasepeeler@gmail.com (Chase Peeler)
On Wed, Sep 2, 2020 at 9:16 AM Josh Bruce <josh@joshbruce.dev> wrote:

> > > On Sep 2, 2020, at 6:27 AM, Dik Takken takken@gmail.com> wrote: > > > > On 02-09-2020 12:48, Olle Härstedt wrote: > >> An alternative syntax would be > >> > >> foreach($iterable as $key => _) { ... } > >> > >> Using underscore as a way to signal "I don't care about this value". > >> Same could be possible with list destructoring, like > >> > >> [_, _, $something] = foo(); > >> > > Swift also uses the underscore in places. > > >> 1. It is currently a valid constant name (BC break) > > I can name a constant an underscore?? > > Does anyone actually do this?? > > I guess I’m asking how impactful the break would be considering most magic > things start with double underscore and I haven’t seen many people using > the single underscore to represent instance variables anymore. > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > Isn't the underscore an alias for gettext()?
-- Chase Peeler chasepeeler@gmail.com
  111781
September 2, 2020 13:57 dik.takken@gmail.com (Dik Takken)
On 02-09-2020 15:35, Chase Peeler wrote:
> Isn't the underscore an alias for gettext()?
You are right, it is. Now this does not necessarily mean that underscore cannot be used for ignored variables. Depending on the context in which it is used an underscore may or may not be ambiguous. Since we are talking about using underscore in places where a variable name is expected, there may not be any problem at all. But we should be aware of all cases in which ambiguous syntax could emerge and identify any issues. So thanks a lot for pointing out this possible trouble maker! Regards, Dik Takken
  111782
September 2, 2020 14:24 david.proweb@gmail.com (David Rodrigues)
I think "void" is a good solution and is very clear, compared to "_".

[void, void, $username] = getUserData();


Atenciosamente,
David Rodrigues


Em qua., 2 de set. de 2020 às 10:57, Dik Takken takken@gmail.com>
escreveu:

> On 02-09-2020 15:35, Chase Peeler wrote: > > Isn't the underscore an alias for gettext()? > > You are right, it is. Now this does not necessarily mean that underscore > cannot be used for ignored variables. Depending on the context in which > it is used an underscore may or may not be ambiguous. > > Since we are talking about using underscore in places where a variable > name is expected, there may not be any problem at all. But we should be > aware of all cases in which ambiguous syntax could emerge and identify > any issues. So thanks a lot for pointing out this possible trouble maker! > > Regards, > Dik Takken > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  111783
September 2, 2020 14:31 mails@thomasbley.de (Thomas Bley)
Hello,

I'd also like to propose to use null:

[null, null, $username] = getUserData();

foreach ($source as $key => null) {}

Regards
Thomas

> David Rodrigues proweb@gmail.com> hat am 02.09.2020 16:24 geschrieben: > > > I think "void" is a good solution and is very clear, compared to "_". > > [void, void, $username] = getUserData(); > > > Atenciosamente, > David Rodrigues > > > Em qua., 2 de set. de 2020 às 10:57, Dik Takken takken@gmail.com> > escreveu: > > > On 02-09-2020 15:35, Chase Peeler wrote: > > > Isn't the underscore an alias for gettext()? > > > > You are right, it is. Now this does not necessarily mean that underscore > > cannot be used for ignored variables. Depending on the context in which > > it is used an underscore may or may not be ambiguous. > > > > Since we are talking about using underscore in places where a variable > > name is expected, there may not be any problem at all. But we should be > > aware of all cases in which ambiguous syntax could emerge and identify > > any issues. So thanks a lot for pointing out this possible trouble maker! > > > > Regards, > > Dik Takken > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > >
  111784
September 2, 2020 16:14 lester@lsces.uk (Lester Caine)
On 02/09/2020 15:31, Thomas Bley wrote:
> I'd also like to propose to use null: > > [null, null, $username] = getUserData(); > > foreach ($source as $key => null) {}
Exactly what null is designed for ... -- Lester Caine - G8HFL ----------------------------- Contact - https://lsces.uk/wiki/Contact L.S.Caine Electronic Services - https://lsces.uk Model Engineers Digital Workshop - https://medw.uk Rainbow Digital Media - https://rainbowdigitalmedia.uk
  111786
September 2, 2020 16:58 ben@benramsey.com (Ben Ramsey)
> On Sep 2, 2020, at 11:14, Lester Caine <lester@lsces.uk> wrote: > > On 02/09/2020 15:31, Thomas Bley wrote: >> I'd also like to propose to use null: >> [null, null, $username] = getUserData(); >> foreach ($source as $key => null) {} > > Exactly what null is designed for ...
I second (or third) `null`. Overall, I like the proposal. Cheers, Ben
  111787
September 2, 2020 17:04 arvids.godjuks@gmail.com (Arvids Godjuks)
On Wed, 2 Sep 2020 at 18:58, Ben Ramsey <ben@benramsey.com> wrote:

> > > On Sep 2, 2020, at 11:14, Lester Caine <lester@lsces.uk> wrote: > > > > On 02/09/2020 15:31, Thomas Bley wrote: > >> I'd also like to propose to use null: > >> [null, null, $username] = getUserData(); > >> foreach ($source as $key => null) {} > > > > Exactly what null is designed for ... > > I second (or third) `null`. > > Overall, I like the proposal. > > Cheers, > Ben > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > I second that, `null` fits very well and easy to understand.
The `_` can be troublesome since there is _() and it can make it a bit troublesome to implement. But regardless, I really love the `null` idea personally. -- Arvīds Godjuks +371 26 851 664 arvids.godjuks@gmail.com Skype: psihius Telegram: @psihius https://t.me/psihius
  111785
September 2, 2020 16:53 pollita@php.net (Sara Golemon)
On Wed, Sep 2, 2020 at 9:31 AM Thomas Bley <mails@thomasbley.de> wrote:

> Hello, > > I'd also like to propose to use null: > > [null, null, $username] = getUserData(); > > foreach ($source as $key => null) {} > > These both look like great, expressive syntaxes. No new keywords, no major
change to existing idioms, just using up some otherwise unused space. 1. Are there other places this idiom might make sense? 2. Should we consider making them separate votes? Or taken as a whole? -Sara
  111788
September 2, 2020 17:05 vorismi3@fel.cvut.cz (=?UTF-8?Q?Michael_Vo=C5=99=C3=AD=C5=A1ek_-_=C4=8CVUT_FEL?=)
I like "void", as "null" can be ambiguous. 

Imagine function example($a = 'default value 1', $b = 'default value 2')
{} 

With "void", we can allow skipping arguments in advance to the default
pamameter value like example(void, 'test');. 

With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem,

Michael Voříšek

On 2 Sep 2020 16:24, David Rodrigues wrote:

> I think "void" is a good solution and is very clear, compared to "_". > > [void, void, $username] = getUserData(); > > Atenciosamente, > David Rodrigues > > Em qua., 2 de set. de 2020 às 10:57, Dik Takken takken@gmail.com> > escreveu: > > On 02-09-2020 15:35, Chase Peeler wrote: Isn't the underscore an alias for gettext()? > You are right, it is. Now this does not necessarily mean that underscore > cannot be used for ignored variables. Depending on the context in which > it is used an underscore may or may not be ambiguous. > > Since we are talking about using underscore in places where a variable > name is expected, there may not be any problem at all. But we should be > aware of all cases in which ambiguous syntax could emerge and identify > any issues. So thanks a lot for pointing out this possible trouble maker! > > Regards, > Dik Takken > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php
  111796
September 2, 2020 20:52 josh@joshbruce.dev (Josh Bruce)
> On Sep 2, 2020, at 12:05 PM, Michael Voříšek - ČVUT FEL <vorismi3@fel.cvut.cz> wrote: > > I like "void", as "null" can be ambiguous. > > Imagine function example($a = 'default value 1', $b = 'default value 2') {} > > With "void", we can allow skipping arguments in advance to the default pamameter value like example(void, 'test');. > I second the use of “void" over “null” - for what it's worth.
Mainly the rationale for me is that I would like to reserve “null” for empty or non-existent object. [ “key” => 1, “key2” => null // empty object ] “void" is already being used on the tail of functions to say, “This thing does not return anything; and can be ignored.” So: foreach($collection as $key => void) Says, “This thing can be ignored” (void) and not, “this thing doesn’t exist but maybe should” (null). Cheers, Johs
  111789
September 2, 2020 17:13 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Sep 2, 2020 at 5:16 AM Mike Schinkel <mike@newclarity.net> wrote:

> This is a new thread for John Bafford's RFC which he mentioned on another > thread, see below: > > https://wiki.php.net/rfc/foreach_void < > https://wiki.php.net/rfc/foreach_void> >
Just like the first time this was discussed, I don't think this RFC makes a sufficient case on why we need explicit syntax for this. Just ignoring the value is an existing pattern that works across all PHP versions: foreach ($iterable as $key => $_) { ... } Introducing special syntax for this has costs, both in terms of language complexity and in terms of implementation complexity. For example, implementing this feature will make foreach (whether or not the value is ignored) marginally slower, because we will have to explicitly distinguish this case. (Or alternatively, we'd have to specialize and increase VM code size -- it's not free in any case.) Iterating over just the keys is not a super common pattern and we already have a reasonable way to do it (that is imho just as clear, and actually more concise than the proposed "null" variant). The only potential advantage to a dedicated syntax that I see is that there could be iterators that can cheaply produce keys, but have expensive to produce values. That seems like an edge case of an edge case though, and is a situation where manually calling ->key() would be justifiable. Regards, Nikita
> On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: > > > > Hi Riikka, > > > >> On Aug 31, 2020, at 14:13, Riikka Kalliomäki < > riikka.kalliomaki@riimu.net> wrote: > >> > >> A common pattern that I've seen that could dearly use PHP internal > >> optimization, if possible, would be: > >> > >> foreach (array_keys($array) as $key) { > >> } > > > > I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch ( > https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I > think) that helps with this, by allowing the following syntax: > > > > foreach($iterable as $key => void) { ... } > > > > This would iterate over the keys of the iterable, and does not retrieve > the values at all. > > > > In theory, this should be a general performance win any time one needs > to iterate over only the keys of an iterable, because it does not require > the use of an O(n) iteration and building of the array that array_keys() > would, plus it works on non-array types (such as generators or iterators).. > It also is more performant than foreach($iterable as $key => $_) {}, > because it omits the opcode that instructs the engine to retrieve the > value. (Presumably, a future direction could include using this request to > inform generators or iterators to only return keys, and not values, which > could further improve performance, especially if value generation is > expensive. But that is out of scope for this RFC.) > > > > If this is something we'd like for PHP 8.1 and there are no major > objections to the idea, then after 8.0 is released, I can move the RFC out > of Draft and into Under Discussion, and presuming a vote passes, I'll > update the patch as necessary to work against 8.0. But my time is limited > and I'm not willing to put further time into the code unless an RFC vote > passes. > > > > Thoughts anyone? > > +1 from me. > > BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to > update that? > > -Mike
  111790
September 2, 2020 17:21 benas.molis.iml@gmail.com (Benas IML)
+1.

I'd also like to mention that other languages don't have any kind of
syntactic sugar/special syntax for iterating over keys. That is achieved
using a function though.

This proposal to me seems a bit like the "return if/guard" RFC i. e. I see
no value in it.

On Wed, Sep 2, 2020, 8:13 PM Nikita Popov ppv@gmail.com> wrote:

> On Wed, Sep 2, 2020 at 5:16 AM Mike Schinkel <mike@newclarity.net> wrote: > > > This is a new thread for John Bafford's RFC which he mentioned on another > > thread, see below: > > > > https://wiki.php.net/rfc/foreach_void < > > https://wiki.php.net/rfc/foreach_void> > > > > Just like the first time this was discussed, I don't think this RFC makes a > sufficient case on why we need explicit syntax for this. Just ignoring the > value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... } > > Introducing special syntax for this has costs, both in terms of language > complexity and in terms of implementation complexity. For example, > implementing this feature will make foreach (whether or not the value is > ignored) marginally slower, because we will have to explicitly distinguish > this case. (Or alternatively, we'd have to specialize and increase VM code > size -- it's not free in any case.) > > Iterating over just the keys is not a super common pattern and we already > have a reasonable way to do it (that is imho just as clear, and actually > more concise than the proposed "null" variant). The only potential > advantage to a dedicated syntax that I see is that there could be iterators > that can cheaply produce keys, but have expensive to produce values. That > seems like an edge case of an edge case though, and is a situation where > manually calling ->key() would be justifiable. > > Regards, > Nikita > > > On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: > > > > > > Hi Riikka, > > > > > >> On Aug 31, 2020, at 14:13, Riikka Kalliomäki < > > riikka.kalliomaki@riimu.net> wrote: > > >> > > >> A common pattern that I've seen that could dearly use PHP internal > > >> optimization, if possible, would be: > > >> > > >> foreach (array_keys($array) as $key) { > > >> } > > > > > > I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch ( > > https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I > > think) that helps with this, by allowing the following syntax: > > > > > > foreach($iterable as $key => void) { ... } > > > > > > This would iterate over the keys of the iterable, and does not retrieve > > the values at all. > > > > > > In theory, this should be a general performance win any time one needs > > to iterate over only the keys of an iterable, because it does not require > > the use of an O(n) iteration and building of the array that array_keys() > > would, plus it works on non-array types (such as generators or > iterators). > > It also is more performant than foreach($iterable as $key => $_) {}, > > because it omits the opcode that instructs the engine to retrieve the > > value. (Presumably, a future direction could include using this request > to > > inform generators or iterators to only return keys, and not values, which > > could further improve performance, especially if value generation is > > expensive. But that is out of scope for this RFC.) > > > > > > If this is something we'd like for PHP 8.1 and there are no major > > objections to the idea, then after 8.0 is released, I can move the RFC > out > > of Draft and into Under Discussion, and presuming a vote passes, I'll > > update the patch as necessary to work against 8.0. But my time is limited > > and I'm not willing to put further time into the code unless an RFC vote > > passes. > > > > > > Thoughts anyone? > > > > +1 from me. > > > > BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to > > update that? > > > > -Mike >
  111799
September 2, 2020 23:45 tysonandre775@hotmail.com (tyson andre)
Hi Benas IML,

> I'd also like to mention that other languages don't have any kind of > syntactic sugar/special syntax for iterating over keys. That is achieved > using a function though.
That's not true, Golang has iterating over keys by default and a more verbose syntax to iterate over values. https://gobyexample.com/range `_` is used to indicate to the compiler that the result should be discarded.. ``` // range on map iterates over key/value pairs. kvs := map[string]string{"a": "apple", "b": "banana"} for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } // iterate over just the keys of a map. for k := range kvs { fmt.Println("key:", k) } // iterate over just the values of a map. for _, v := range kvs { fmt.Println("key:", k) } ``` Cheers, - Tyson
  111792
September 2, 2020 18:47 chasepeeler@gmail.com (Chase Peeler)
On Wed, Sep 2, 2020 at 1:13 PM Nikita Popov ppv@gmail.com> wrote:

> On Wed, Sep 2, 2020 at 5:16 AM Mike Schinkel <mike@newclarity.net> wrote: > > > This is a new thread for John Bafford's RFC which he mentioned on another > > thread, see below: > > > > https://wiki.php.net/rfc/foreach_void < > > https://wiki.php.net/rfc/foreach_void> > > > > Just like the first time this was discussed, I don't think this RFC makes a > sufficient case on why we need explicit syntax for this. Just ignoring the > value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... } > > Introducing special syntax for this has costs, both in terms of language > complexity and in terms of implementation complexity. For example, > implementing this feature will make foreach (whether or not the value is > ignored) marginally slower, because we will have to explicitly distinguish > this case. (Or alternatively, we'd have to specialize and increase VM code > size -- it's not free in any case.) > > There were two justifications given in the RFC. The first was that $key =>
$value and ignoring the value has performance costs. You indicate there would be a cost to dealing with a special character there in order to know whether or not to ignore the value. So, I think the question is which one causes the bigger performance hit. The other justification was semantic. I don't personally find that justification for the change, especially if we could actually be looking at performance implications.
> Iterating over just the keys is not a super common pattern and we already > have a reasonable way to do it (that is imho just as clear, and actually > more concise than the proposed "null" variant). The only potential > advantage to a dedicated syntax that I see is that there could be iterators > that can cheaply produce keys, but have expensive to produce values. That > seems like an edge case of an edge case though, and is a situation where > manually calling ->key() would be justifiable. > > Regards, > Nikita > > > On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: > > > > > > Hi Riikka, > > > > > >> On Aug 31, 2020, at 14:13, Riikka Kalliomäki < > > riikka.kalliomaki@riimu.net> wrote: > > >> > > >> A common pattern that I've seen that could dearly use PHP internal > > >> optimization, if possible, would be: > > >> > > >> foreach (array_keys($array) as $key) { > > >> } > > > > > > I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch ( > > https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I > > think) that helps with this, by allowing the following syntax: > > > > > > foreach($iterable as $key => void) { ... } > > > > > > This would iterate over the keys of the iterable, and does not retrieve > > the values at all. > > > > > > In theory, this should be a general performance win any time one needs > > to iterate over only the keys of an iterable, because it does not require > > the use of an O(n) iteration and building of the array that array_keys() > > would, plus it works on non-array types (such as generators or > iterators). > > It also is more performant than foreach($iterable as $key => $_) {}, > > because it omits the opcode that instructs the engine to retrieve the > > value. (Presumably, a future direction could include using this request > to > > inform generators or iterators to only return keys, and not values, which > > could further improve performance, especially if value generation is > > expensive. But that is out of scope for this RFC.) > > > > > > If this is something we'd like for PHP 8.1 and there are no major > > objections to the idea, then after 8.0 is released, I can move the RFC > out > > of Draft and into Under Discussion, and presuming a vote passes, I'll > > update the patch as necessary to work against 8.0. But my time is limited > > and I'm not willing to put further time into the code unless an RFC vote > > passes. > > > > > > Thoughts anyone? > > > > +1 from me. > > > > BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to > > update that? > > > > -Mike >
-- Chase Peeler chasepeeler@gmail.com
  111794
September 2, 2020 19:31 dik.takken@gmail.com (Dik Takken)
On 02-09-2020 19:13, Nikita Popov wrote:
> Just like the first time this was discussed, I don't think this RFC makes a > sufficient case on why we need explicit syntax for this. Just ignoring the > value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... }
While this works fine, it does introduce an unused variable. Code inspection currently complains about that, and for good reason, which is annoying. Even if we decide that it is not worth the trouble for foreach loops, there are other cases where this new syntax can work well. Array destructuring has already been mentioned. Another case is the one where a function intentionally does not use one of the arguments passed to it. This happens easily when using callbacks or when implementing interfaces. A function declaration could look like this: function foo($arg, void) {} This indicates that the second parameter is intentionally left unused. Perhaps it is a good idea to generalize the RFC to the general concept of "using void to intentionally ignore a variable". Maybe pick just one use case for actual implementation and extend later using followup RFCs. Regards, Dik Takken
  111795
September 2, 2020 19:53 dik.takken@gmail.com (Dik Takken)
On 02-09-2020 21:31, Dik Takken wrote:
> Even if we decide that it is not worth the trouble for foreach loops, > there are other cases where this new syntax can work well. Array > destructuring has already been mentioned.
Replying to myself: It just occurred to me that array destructuring already allows omitting values: [, , $username] = getUserData(); I still do find using void here more clear though, more intentional.
> Another case is the one where a function intentionally does not use one > of the arguments passed to it. This happens easily when using callbacks > or when implementing interfaces. A function declaration could look like > this: > > function foo($arg, void) {} >
Given the array destructuring syntax, an alternative syntax might be: function foo($arg,) Again, I would prefer to see void here in stead of a trailing comma. In function calls a trailing comma is already allowed and it has a completely different meaning, which can be confusing. Regards, Dik Takken
  111797
September 2, 2020 20:58 olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=)
On Wed, 2 Sep 2020, 21:54 Dik Takken, takken@gmail.com> wrote:

> On 02-09-2020 21:31, Dik Takken wrote: > > Even if we decide that it is not worth the trouble for foreach loops, > > there are other cases where this new syntax can work well. Array > > destructuring has already been mentioned. > > Replying to myself: It just occurred to me that array destructuring > already allows omitting values: > > [, , $username] = getUserData(); > > I still do find using void here more clear though, more intentional. >
Yes, the current syntax lacks explicit intent and looks like a syntax error. Anything would be better than this, I think. :)
> > Another case is the one where a function intentionally does not use one > > of the arguments passed to it. This happens easily when using callbacks > > or when implementing interfaces. A function declaration could look like > > this: > > > > function foo($arg, void) {} > > > > Given the array destructuring syntax, an alternative syntax might be: > > function foo($arg,) > > Again, I would prefer to see void here in stead of a trailing comma. In > function calls a trailing comma is already allowed and it has a > completely different meaning, which can be confusing. > > Regards, > Dik Takken > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  111813
September 3, 2020 12:14 me@jhdxr.com (=?utf-8?b?Q0hVIFpoYW93ZWk=?=)
Regarding the unused variable, I think OPCache should be able to identify and eliminate it. I don't think it's necessary to add a new syntax here.

Array destructuring sounds like a similar case to me. If you don't like [, , $v] =$arr, you can use [$_, $_, $v]=$arr instead.

Regards,
CHU Zhaowei

-----Original Message-----
From: Dik Takken takken@gmail.com> 
Sent: Thursday, September 3, 2020 3:31 AM
To: Nikita Popov ppv@gmail.com>; Mike Schinkel <mike@newclarity.net>
Cc: John Bafford <jbafford@zort.net>; PHP internals <internals@lists.php.net>
Subject: Re: [PHP-DEV] Draft RFC: foreach iteration of keys without values

On 02-09-2020 19:13, Nikita Popov wrote:
> Just like the first time this was discussed, I don't think this RFC > makes a sufficient case on why we need explicit syntax for this. Just > ignoring the value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... }
While this works fine, it does introduce an unused variable. Code inspection currently complains about that, and for good reason, which is annoying. Even if we decide that it is not worth the trouble for foreach loops, there are other cases where this new syntax can work well. Array destructuring has already been mentioned. Another case is the one where a function intentionally does not use one of the arguments passed to it. This happens easily when using callbacks or when implementing interfaces. A function declaration could look like this: function foo($arg, void) {} This indicates that the second parameter is intentionally left unused. Perhaps it is a good idea to generalize the RFC to the general concept of "using void to intentionally ignore a variable". Maybe pick just one use case for actual implementation and extend later using followup RFCs. Regards, Dik Takken -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
  111802
September 3, 2020 07:27 riikka.kalliomaki@riimu.net (=?UTF-8?Q?Riikka_Kalliom=C3=A4ki?=)
> Iterating over just the keys is not a super common pattern and we already have a reasonable way to do it (that is imho just as clear, and actually
more concise than the proposed "null" variant). The reason I in my previous message suggested the engine optimization for the "foreach (array_keys($array) as $val)", is because I feel that iterating over the keys of arrays is, in my experience, a relatively common pattern. The reason is that array keys are occasionally used for storing things like strings or numbers, especially when you need a simple to implement unique list. On the other hand, I have never had the need to specifically iterate over the keys of an iterator. Additionally, I feel that there are other advantages to (at least) implementing that optimization: - The engine itself does not necessarily need to handle it differently from normal foreach. Maybe the engine could, in fact, treat it just like "foreach ($array as $val => $_)" - This is a pattern that I already see happening a lot in existing code, so optimizing this case would give some benefits to existing implementation - This would not require any changes to existing php syntax - Should special syntax be introduced later, this case could be converted into that syntax at that point While the disadvantage of doing just this is that you can't easily apply it to iterators, the thing is that iterators are already calling other functions. The point here is to apply additional context awareness to avoid unnecessary execution on existing language constructs. I would see this more akin to dead code optimization than a language feature. On Wed, Sep 2, 2020 at 8:14 PM Nikita Popov ppv@gmail.com> wrote:
> > On Wed, Sep 2, 2020 at 5:16 AM Mike Schinkel <mike@newclarity.net> wrote: > > > This is a new thread for John Bafford's RFC which he mentioned on another > > thread, see below: > > > > https://wiki.php.net/rfc/foreach_void < > > https://wiki.php.net/rfc/foreach_void> > > > > Just like the first time this was discussed, I don't think this RFC makes a > sufficient case on why we need explicit syntax for this. Just ignoring the > value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... } > > Introducing special syntax for this has costs, both in terms of language > complexity and in terms of implementation complexity. For example, > implementing this feature will make foreach (whether or not the value is > ignored) marginally slower, because we will have to explicitly distinguish > this case. (Or alternatively, we'd have to specialize and increase VM code > size -- it's not free in any case.) > > Iterating over just the keys is not a super common pattern and we already > have a reasonable way to do it (that is imho just as clear, and actually > more concise than the proposed "null" variant). The only potential > advantage to a dedicated syntax that I see is that there could be iterators > that can cheaply produce keys, but have expensive to produce values. That > seems like an edge case of an edge case though, and is a situation where > manually calling ->key() would be justifiable. > > Regards, > Nikita > > > On Aug 31, 2020, at 5:50 PM, John Bafford <jbafford@zort.net> wrote: > > > > > > Hi Riikka, > > > > > >> On Aug 31, 2020, at 14:13, Riikka Kalliomäki < > > riikka.kalliomaki@riimu.net> wrote: > > >> > > >> A common pattern that I've seen that could dearly use PHP internal > > >> optimization, if possible, would be: > > >> > > >> foreach (array_keys($array) as $key) { > > >> } > > > > > > I have a draft RFC (https://wiki.php.net/rfc/foreach_void) and patch ( > > https://github.com/jbafford/php-src/tree/foreachvoid against php 7.0, I > > think) that helps with this, by allowing the following syntax: > > > > > > foreach($iterable as $key => void) { ... } > > > > > > This would iterate over the keys of the iterable, and does not retrieve > > the values at all. > > > > > > In theory, this should be a general performance win any time one needs > > to iterate over only the keys of an iterable, because it does not require > > the use of an O(n) iteration and building of the array that array_keys() > > would, plus it works on non-array types (such as generators or iterators). > > It also is more performant than foreach($iterable as $key => $_) {}, > > because it omits the opcode that instructs the engine to retrieve the > > value. (Presumably, a future direction could include using this request to > > inform generators or iterators to only return keys, and not values, which > > could further improve performance, especially if value generation is > > expensive. But that is out of scope for this RFC.) > > > > > > If this is something we'd like for PHP 8.1 and there are no major > > objections to the idea, then after 8.0 is released, I can move the RFC out > > of Draft and into Under Discussion, and presuming a vote passes, I'll > > update the patch as necessary to work against 8.0. But my time is limited > > and I'm not willing to put further time into the code unless an RFC vote > > passes. > > > > > > Thoughts anyone? > > > > +1 from me. > > > > BTW, your RFC says "Next PHP 7.x" for Proposed Version; might need to > > update that? > > > > -Mike
-- Riikka Kalliomäki https://github.com/Riimu
  111804
September 3, 2020 07:58 come.chilliet@fusiondirectory.org (=?UTF-8?B?Q8O0bWU=?= Chilliet)
Le Wed, 2 Sep 2020 19:13:20 +0200,
Nikita Popov ppv@gmail.com> a écrit :
> Just like the first time this was discussed, I don't think this RFC makes a > sufficient case on why we need explicit syntax for this. Just ignoring the > value is an existing pattern that works across all PHP versions: > > foreach ($iterable as $key => $_) { ... }
I currently use foreach (array_keys($array) as $key) { ... } to avoid complains from code analysers on unused var, is it slower? One obvious pro of having a dedicated syntax is not having to ask those questions to ourselves while coding.
> Iterating over just the keys is not a super common pattern and we already > have a reasonable way to do it (that is imho just as clear, and actually > more concise than the proposed "null" variant). The only potential > advantage to a dedicated syntax that I see is that there could be iterators > that can cheaply produce keys, but have expensive to produce values. That > seems like an edge case of an edge case though, and is a situation where > manually calling ->key() would be justifiable.
In our code base I thinks it is quite common. grepping on "foreach (array_keys" gives me 51 cases, while grepping "foreach (" gives me 1153, so that’s 4% of our foreach uses. Côme
  111808
September 3, 2020 09:18 markus@fischer.name (Markus Fischer)
Hi,

On 03.09.20 09:58, Côme Chilliet wrote:
>> >> foreach ($iterable as $key => $_) { ... } > > I currently use foreach (array_keys($array) as $key) { ... } > to avoid complains from code analysers on unused var, is it slower?
one argument brought forward initially (sorry, can't find the email right now) is the resource management: array_keys() has to create a copy [*] which might be an issue depending on the size of data. - Markus [*] I now about shallow-copy, I'm just trying to cite the initial argument as best as I can :)
  111819
September 3, 2020 14:31 pollita@php.net (Sara Golemon)
On Thu, Sep 3, 2020 at 4:19 AM Markus Fischer <markus@fischer.name> wrote:

> > I currently use foreach (array_keys($array) as $key) { ... } > > to avoid complains from code analysers on unused var, is it slower? > > one argument brought forward initially (sorry, can't find the email > right now) is the resource management: array_keys() has to create a copy > [*] which might be an issue depending on the size of data. > > While I like the idea of more explicit syntax to show intent over a mere
convention of $_ being an ignorable var, I do need to call out the foreach (array_keys(...) argument as being a poor motivator. IF (and I heavily stress "if" here) this pattern is common among people trying to show explicit intent and IF it represents a noticeable slowdown, then the solution for it is for the engine to optimize around that by transforming it during compile time. That lets us fix all usages instantaneously without user interaction, and more importantly it allows users to focus on their code being readable (and thereby maintainable) according to whatever coding standards they choose to apply. Again, that same argument is why I actually like the proposal overall. Not because it's so much more performant, but because it empowers developers to write code in a way that will be most readable and maintainable to them, should they happen to just not like the $_ unused var pattern (which is a legit thing to dislike). -Sara
  111823
September 3, 2020 15:11 internals@lists.php.net ("Levi Morrison via internals")
On Thu, Sep 3, 2020 at 8:32 AM Sara Golemon <pollita@php.net> wrote:
> > On Thu, Sep 3, 2020 at 4:19 AM Markus Fischer <markus@fischer.name> wrote: > > > > I currently use foreach (array_keys($array) as $key) { ... } > > > to avoid complains from code analysers on unused var, is it slower? > > > > one argument brought forward initially (sorry, can't find the email > > right now) is the resource management: array_keys() has to create a copy > > [*] which might be an issue depending on the size of data. > > > > > While I like the idea of more explicit syntax to show intent over a mere > convention of $_ being an ignorable var, I do need to call out the foreach > (array_keys(...) argument as being a poor motivator. > > IF (and I heavily stress "if" here) this pattern is common among people > trying to show explicit intent and IF it represents a noticeable slowdown, > then the solution for it is for the engine to optimize around that by > transforming it during compile time. That lets us fix all usages > instantaneously without user interaction, and more importantly it allows > users to focus on their code being readable (and thereby maintainable) > according to whatever coding standards they choose to apply. > > Again, that same argument is why I actually like the proposal overall. Not > because it's so much more performant, but because it empowers developers to > write code in a way that will be most readable and maintainable to them, > should they happen to just not like the $_ unused var pattern (which is a > legit thing to dislike). > > -Sara
Question for those who know about opcache optimizations: is it feasible to avoid fetching the current value if the value is otherwise unused and the variable-variable features are not used either?
  111824
September 3, 2020 15:35 david.proweb@gmail.com (David Rodrigues)
Do you think that it could be proxied? I mean, optimize foreach
(array_keys()...) syntax to not call array_keys() in fact, but a optimized
version of foreach to handle key only. I don't know it opcache could do
that, and if it already does.

Em qui, 3 de set de 2020 12:12, Levi Morrison via internals <
internals@lists.php.net> escreveu:

> On Thu, Sep 3, 2020 at 8:32 AM Sara Golemon <pollita@php.net> wrote: > > > > On Thu, Sep 3, 2020 at 4:19 AM Markus Fischer <markus@fischer.name> > wrote: > > > > > > I currently use foreach (array_keys($array) as $key) { ... } > > > > to avoid complains from code analysers on unused var, is it slower? > > > > > > one argument brought forward initially (sorry, can't find the email > > > right now) is the resource management: array_keys() has to create a > copy > > > [*] which might be an issue depending on the size of data. > > > > > > > > While I like the idea of more explicit syntax to show intent over a mere > > convention of $_ being an ignorable var, I do need to call out the > foreach > > (array_keys(...) argument as being a poor motivator. > > > > IF (and I heavily stress "if" here) this pattern is common among people > > trying to show explicit intent and IF it represents a noticeable > slowdown, > > then the solution for it is for the engine to optimize around that by > > transforming it during compile time. That lets us fix all usages > > instantaneously without user interaction, and more importantly it allows > > users to focus on their code being readable (and thereby maintainable) > > according to whatever coding standards they choose to apply. > > > > Again, that same argument is why I actually like the proposal overall. > Not > > because it's so much more performant, but because it empowers developers > to > > write code in a way that will be most readable and maintainable to them, > > should they happen to just not like the $_ unused var pattern (which is a > > legit thing to dislike). > > > > -Sara > > Question for those who know about opcache optimizations: is it > feasible to avoid fetching the current value if the value is otherwise > unused and the variable-variable features are not used either? > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  111826
September 3, 2020 15:52 ocramius@gmail.com (Marco Pivetta)
On Thu, Sep 3, 2020 at 5:35 PM David Rodrigues proweb@gmail.com>
wrote:

> > Question for those who know about opcache optimizations: is it > > feasible to avoid fetching the current value if the value is otherwise > > unused and the variable-variable features are not used either? >
TBH, this sounds like the best approach: optimizing the `foreach (\array_keys($input) as $key) {` structure, when detected. That would make it zero impact from an RFC/userland perspective, and the OP by John is in fact about a performance concern, while we already have a very expressive way to do key iteration. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  111829
September 3, 2020 16:04 pollita@php.net (Sara Golemon)
On Thu, Sep 3, 2020 at 10:35 AM David Rodrigues proweb@gmail.com>
wrote:

> Do you think that it could be proxied? I mean, optimize foreach > (array_keys()...) syntax to not call array_keys() in fact, but a optimized > version of foreach to handle key only. I don't know it opcache could do > that, and if it already does. > > I wouldn't use the word "proxied", but yes. In my mind the compiler would
see: foreach(\array_keys($arr) as $key) { and quietly transform that into: foreach ($arr as $key => $_unusedVariableNameThatIsntEvenSpilledToTheScope) { Thus not iterating the array twice and creating a temporary array of key names. -Sara
  111831
September 3, 2020 16:11 benas.molis.iml@gmail.com (Benas IML)
On Thu, Sep 3, 2020, 7:05 PM Sara Golemon <pollita@php.net> wrote:

> On Thu, Sep 3, 2020 at 10:35 AM David Rodrigues proweb@gmail.com> > wrote: > > > Do you think that it could be proxied? I mean, optimize foreach > > (array_keys()...) syntax to not call array_keys() in fact, but a > optimized > > version of foreach to handle key only. I don't know it opcache could do > > that, and if it already does. > > > > > I wouldn't use the word "proxied", but yes. In my mind the compiler would > see: > > foreach(\array_keys($arr) as $key) { > > and quietly transform that into: > > foreach ($arr as $key => $_unusedVariableNameThatIsntEvenSpilledToTheScope) > { > > Thus not iterating the array twice and creating a temporary array of key > names. >
Good idea; since I'm kind of bored, I'll try to implement a prototype myself during my free time. -Sara
>
  111835
September 3, 2020 20:08 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 3, 2020 at 12:05 PM Sara Golemon <pollita@php.net> wrote:

> On Thu, Sep 3, 2020 at 10:35 AM David Rodrigues proweb@gmail.com> > wrote: > > > Do you think that it could be proxied? I mean, optimize foreach > > (array_keys()...) syntax to not call array_keys() in fact, but a > optimized > > version of foreach to handle key only. I don't know it opcache could do > > that, and if it already does. > > > > > I wouldn't use the word "proxied", but yes. In my mind the compiler would > see: > > foreach(\array_keys($arr) as $key) { > > and quietly transform that into: > > foreach ($arr as $key => $_unusedVariableNameThatIsntEvenSpilledToTheScope) > { > > Are there other instances where we have optimizations like this? If so, are
they documented? In terms of readability, I'm more likely to do $keys = array_keys($array); foreach($keys as $key){ That would obviously break the optimization we're talking about though. Which makes me wonder if there are other places like that.
> Thus not iterating the array twice and creating a temporary array of key > names. > > -Sara >
-- Chase Peeler chasepeeler@gmail.com
  111837
September 3, 2020 21:12 josh@joshbruce.dev (Josh Bruce)
> > In terms of readability, I'm more likely to do > $keys = array_keys($array); > foreach($keys as $key){
Fair point. I would too. I have actually forgone even grabbing the keys and just using the loop without touching value in the body. Cheers, Josh
  111838
September 3, 2020 23:22 jbafford@zort.net (John Bafford)
Hi everyone,

Apologies for not including context and responding to 40 emails all at once, I’m not at a computer (and won’t be for a few weeks).

Given the comments I read in the thread, I wanted to make some key points that I hope will clarify my intent behind the proposal:

* The primary motivation behind this RFC is the ability to indicate intent when iterating over a collection without caring about its values. Any performance benefits are strictly secondary.

* I explicitly chose void, rather than null, because in PHP, null is a value, and personally, I found it exceedingly weird to write `foreach($arr as $key => something-that-is-normally-a-value-except-in-this-case)`. In fact, if I’m remembering correctly, I actually waited until PHP 7.1 added `void` for this RFC specifically so I wouldn’t have to invent new syntax.)

* If PHP had either convention or special handling for _ or $_ as a “ignore this” destination, I wouldn’t have made the proposal.  However, it doesn’t; _ can (apparently!) be a constant, and is also a function, and $_ has no special handling (and I bet it’s actually used to contain values that are used in at least one application).

* From my recollection, unless something has changed drastically since 7.0 and 8.x, the only possible performance hit from the patch would be in the parser, as there is obviously some additional logic. However, at runtime, it can only be faster, because in the presence of a `void` foreach value target, the parser simply doesn’t emit the opcode for writing a value there..

* I know it’s popular to say that `foreach(array_keys())` is rare; however, _every_ PHP application I’ve ever touched uses it at least once, and often multiple times. So, I’m equally surprised to find that there are people who have never used it. (If I had to guess, it’s that I make heavy use of the fact that arrays are ordered maps, and so, simply the keys and their order _are_ often a significant and useful piece of information on their own, especially in arrays that are used as mapping tables.)

I think that covers all the criticisms I saw, but if I missed anything, please let me know and I’ll respond once I have a chance. After I get back home, I’ll update the RFC with the results of this thread and bring it to a vote.

Thanks,

-John
  111867
September 16, 2020 02:00 josh@joshbruce.dev (Josh Bruce)
> * If PHP had either convention or special handling for _ or $_ as a “ignore this” destination, I wouldn’t have made the proposal. However, it doesn’t; _ can (apparently!) be a constant, and is also a function, and $_ has no special handling (and I bet it’s actually used to contain values that are used in at least one application).
Saw this today and the list() each() made me think of this thread: https://www.dyn-web.com/php/arrays/iterate/ With you on void for same reason and what if the double-arrow was all that was needed, like the empty + comma in the link: foreach ($arr as $key =>) Cheers, Josh
  111868
September 16, 2020 02:47 andreas@dqxtech.net (Andreas Hennings)
On Wed, 16 Sep 2020 at 04:00, Josh Bruce <josh@joshbruce.dev> wrote:

> > > * If PHP had either convention or special handling for _ or $_ as a > “ignore this” destination, I wouldn’t have made the proposal. However, it > doesn’t; _ can (apparently!) be a constant, and is also a function, and $_ > has no special handling (and I bet it’s actually used to contain values > that are used in at least one application). > > Saw this today and the list() each() made me think of this thread: > https://www.dyn-web.com/php/arrays/iterate/ > > With you on void for same reason and what if the double-arrow was all that > was needed, like the empty + comma in the link: > > foreach ($arr as $key =>) >
I like this! Once you get over the perception that something is missing, it is quite obvious what is going on. Otherwise, I prefer "foreach ($arr as $key => void)" over "foreach ($arr as $key => null)". With "=> null" one might think this is a fancy alternative to array_filter(). "void" is more explicitly "not a value". The array_keys() does not work for iterators. And even on arrays it can be a waste if we are only interested in the first few keys. Optimization could mitigate this. But I would imagine that most people would look at the code and say "that looks wasteful", because the optimization is not visible or obvious. If this does not get added to the language, I can live with "=> $_". PhpStorm already has an option to ignore unused value in foreach(), if a key exists. It is not based on the variable name, but this could be added if people ask for it. -- Andreas
> > Cheers, > Josh
  111834
September 3, 2020 19:54 dik.takken@gmail.com (Dik Takken)
On 02-09-2020 19:13, Nikita Popov wrote:
> > Introducing special syntax for this has costs, both in terms of language > complexity and in terms of implementation complexity. For example, > implementing this feature will make foreach (whether or not the value is > ignored) marginally slower, because we will have to explicitly distinguish > this case. (Or alternatively, we'd have to specialize and increase VM code > size -- it's not free in any case.) >
Regarding the performance / complexity concern, just some possibly naive idea from a non-expert: Could this not be implemented in the compilation phase only, without changing any of the run time code? Maybe the 'void' could be compiled into an opcode sequence that still introduces a variable holding the keys. Execution remains unchanged. So the only thing that 'void' does is ask PHP to implicitly create a hidden variable in stead of the programmer explicitly creating a visible one. Ok, now just say "That's nonsense" and I will shut up. :) Regards, Dik Takken
  111798
September 2, 2020 21:54 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

>> In theory, this should be a general performance win any time one >> needs to iterate over only the keys of an iterable, because it does >> not require the use of an O(n) iteration and building of the array >> that array_keys() would, plus it works on non-array types (such as >> generators or iterators). It also is more performant than >> foreach($iterable as $key => $_) {}, because it omits the opcode >> that instructs the engine to retrieve the value. (Presumably, a >> future direction could include using this request to inform >> generators or
To me, it looks like the case of premature micro-optimization. Unless there's a benchmark that proves it achieves speedup in a real-life application (not tight-loop synthetic benchmark) I think foreach($iterable as $key => $_) {} is completely fine. My opinion has been and remains, absent new data, that if your code performance hinges on a couple of simple opcodes being there, maybe you'd better implement that part in C, but in most real-life applications it is not and any performance gain you might get from such syntax is microscopic. -- Stas Malyshev smalyshev@gmail.com
  111800
September 3, 2020 04:06 mike@newclarity.net (Mike Schinkel)
> On Sep 2, 2020, at 5:54 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >>> In theory, this should be a general performance win any time one >>> needs to iterate over only the keys of an iterable, because it does >>> not require the use of an O(n) iteration and building of the array >>> that array_keys() would, plus it works on non-array types (such as >>> generators or iterators). It also is more performant than >>> foreach($iterable as $key => $_) {}, because it omits the opcode >>> that instructs the engine to retrieve the value. (Presumably, a >>> future direction could include using this request to inform >>> generators or > > To me, it looks like the case of premature micro-optimization. Unless > there's a benchmark that proves it achieves speedup in a real-life > application (not tight-loop synthetic benchmark) I think > foreach($iterable as $key => $_) {} is completely fine. My opinion has > been and remains, absent new data, that if your code performance hinges > on a couple of simple opcodes being there, maybe you'd better implement > that part in C, but in most real-life applications it is not and any > performance gain you might get from such syntax is microscopic.
If it adds a micro-optimization, great, but allowing a developer to explicitly signal intent is the primary argument for adding void. IMO. -Mike
  111801
September 3, 2020 07:18 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> If it adds a micro-optimization, great, but allowing a developer to > explicitly signal intent is the primary argument for adding void. > IMO.
You can signal intent by using $_ or $dummy or whatever. You don't need new language construct each time for each way of using or not using a variable. -- Stas Malyshev smalyshev@gmail.com
  111803
September 3, 2020 07:38 brendt@stitcher.io (Brent Roose)
Hi all

I want to point out the use-case when you're using CS tools, static analysers and IDEs: they report unused variables as errors. There are ways around those errors, but it's more convenient if there's language support. I'd say that conceptually it's also more correct: if you're not using a variable, it shouldn't be there.

As some of you have shown, there are ways achieve the same result without adding new syntax. Just like we didn't need short closures and keep using the normal closure syntax, like we could write if statements and didn't need the nullsafe operator, like we didn't need named arguments or constructor property promotion. I think the past years of PHP devlopment have shown that the majority likes convenient langague syntax and constructs, not because it's absolutely necessary, but because it's just a little more clean, a little less verbose, a bit more convenient.

PHP has been maturing over the last years, which means there's room, and need, for things that aren't strictly necessary.

Kind regards
Brent

> On 3 Sep 2020, at 09:18, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >> If it adds a micro-optimization, great, but allowing a developer to >> explicitly signal intent is the primary argument for adding void. >> IMO. > > You can signal intent by using $_ or $dummy or whatever. You don't need > new language construct each time for each way of using or not using a > variable. > > -- > Stas Malyshev > smalyshev@gmail.com > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >
  111805
September 3, 2020 08:19 dik.takken@gmail.com (Dik Takken)
On 03-09-2020 09:38, Brent Roose wrote:
> Hi all > > I want to point out the use-case when you're using CS tools, static analysers and IDEs: they report unused variables as errors. There are ways around those errors, but it's more convenient if there's language support. I'd say that conceptually it's also more correct: if you're not using a variable, it shouldn't be there.
Exactly this. The intent of a particular language construct does not only need to be clear to human readers but also to machines. More explicit intent leads to stronger static code analysis tools, which helps us catch more bugs earlier. Regards, Dik Takken
  111806
September 3, 2020 08:25 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Sep 3, 2020 at 10:19 AM Dik Takken takken@gmail.com> wrote:

> On 03-09-2020 09:38, Brent Roose wrote: > > Hi all > > > > I want to point out the use-case when you're using CS tools, static > analysers and IDEs: they report unused variables as errors. There are ways > around those errors, but it's more convenient if there's language support. > I'd say that conceptually it's also more correct: if you're not using a > variable, it shouldn't be there. > > Exactly this. > > The intent of a particular language construct does not only need to be > clear to human readers but also to machines. More explicit intent leads > to stronger static code analysis tools, which helps us catch more bugs > earlier. > > Regards, > Dik Takken >
Static analysis tools don't need a language feature to support this. They can recognize the $_ pattern and not emit an unused variable warning for it. I'd suggest submitting a feature request. Nikita
  111816
September 3, 2020 13:07 larry@garfieldtech.com ("Larry Garfield")
On Thu, Sep 3, 2020, at 3:25 AM, Nikita Popov wrote:
> On Thu, Sep 3, 2020 at 10:19 AM Dik Takken takken@gmail.com> wrote: > > > On 03-09-2020 09:38, Brent Roose wrote: > > > Hi all > > > > > > I want to point out the use-case when you're using CS tools, static > > analysers and IDEs: they report unused variables as errors. There are ways > > around those errors, but it's more convenient if there's language support. > > I'd say that conceptually it's also more correct: if you're not using a > > variable, it shouldn't be there. > > > > Exactly this. > > > > The intent of a particular language construct does not only need to be > > clear to human readers but also to machines. More explicit intent leads > > to stronger static code analysis tools, which helps us catch more bugs > > earlier. > > > > Regards, > > Dik Takken > > > > Static analysis tools don't need a language feature to support this. They > can recognize the $_ pattern and not emit an unused variable warning for > it. I'd suggest submitting a feature request. > > Nikita
I agree here. _ is already a common pattern in other languages for a placeholder ignored variable. It's not a big jump for PHP static analyzers to start ignoring unused $_ variables, and it requires no language changes or formal standards. I am skeptical of any performance difference, but from a reader-communication point of view a de facto convention of $_ == unused, and analyzers recognizing that, seems like the path of least resistance. --Larry Garfield
  111822
September 3, 2020 15:11 dik.takken@gmail.com (Dik Takken)
On 03-09-2020 15:07, Larry Garfield wrote:
> > I agree here. _ is already a common pattern in other languages for a placeholder ignored variable. It's not a big jump for PHP static analyzers to start ignoring unused $_ variables, and it requires no language changes or formal standards. >
Technically that will work. However, this needs to rely on some unwritten undocumented convention that all of the user community agrees on and is aware of. Such a convention can be established and documented of course, it worked for doc comments as well. Apparently the PHPMD project considered a change to recognize $_ as an ignored variable. It was declined: https://github.com/phpmd/phpmd/issues/326 In stead, configuration was added to allow specifying a variable name that is to be ignored. Still, every individual user needs to manually configure it and pick a name for ignored variables. For one use case, using $_ simply does not appear to be an option, while using void is. This is the use case of ignoring an argument that is passed to a function: function foo($_) {} This can work but it changes the name of the parameter. That is not the intent at all. It breaks in inheritance scenarios. When it is called and the parameter name is specified as the parent defines it, a fatal error results. What I like about using void is that it has clear intent, it requires no configuration of static analyzers and it provides a single syntax that works for all use cases: foreach, destructuring and function parameters. Regards, Dik Takken
  111807
September 3, 2020 08:27 kontakt@beberlei.de
Von meinem iPhone gesendet

> Am 03.09.2020 um 09:39 schrieb Brent Roose <brendt@stitcher.io>: > > Hi all > > I want to point out the use-case when you're using CS tools, static analysers and IDEs: they report unused variables as errors. There are ways around those errors, but it's more convenient if there's language support. I'd say that conceptually it's also more correct: if you're not using a variable, it shouldn't be there. >
These tools all work with documentation conventions already, it would be much easier they standardise on $_ to allow being unused instead of changing the language.
> As some of you have shown, there are ways achieve the same result without adding new syntax. Just like we didn't need short closures and keep using the normal closure syntax, like we could write if statements and didn't need the nullsafe operator, like we didn't need named arguments or constructor property promotion. I think the past years of PHP devlopment have shown that the majority likes convenient langague syntax and constructs, not because it's absolutely necessary, but because it's just a little more clean, a little less verbose, a bit more convenient. > > PHP has been maturing over the last years, which means there's room, and need, for things that aren't strictly necessary. > > Kind regards > Brent > >> On 3 Sep 2020, at 09:18, Stanislav Malyshev <smalyshev@gmail.com> wrote: >> >> Hi! >> >>> If it adds a micro-optimization, great, but allowing a developer to >>> explicitly signal intent is the primary argument for adding void. >>> IMO. >> >> You can signal intent by using $_ or $dummy or whatever. You don't need >> new language construct each time for each way of using or not using a >> variable. >> >> -- >> Stas Malyshev >> smalyshev@gmail.com >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php >> >