[RFC] foreach_variable supporting T_LIST

php.internals

Laruence

14 years ago
Hi: this is not a new RFC, I proposed it before, but due to my poor english and improper examples, it didn't get passed. This feature introduces list() support in foreach constructs(more info can be found here: https://wiki.php.net/rfc/foreachlist): <?php $users = array( array('Foo', 'Bar'), array('Baz', 'Qux'); ); // Before foreach ($users as $user) { list($firstName, $lastName) = $user; echo "First name: $firstName, last name: $lastName. "; } // After foreach ($users as list($firstName, $lastName)) { echo "First name: $firstName, last name: $lastName. "; } ?> what do you think? personally, I really think it's a good feature. what about commit this into trunk(php 5.5) ? thanks
-- Laruence Xinchen Hui http://www.laruence.com/

Andrew Faulds

14 years ago
Sounds great. Python has something similar for tuples, would be good if PHP had this. Are there any BC concerns? Don't see why this could break something. On Jul 18, 2012 3:50 PM, "Laruence" <laruence@php.net> wrote:

Laruence

14 years ago
On Wed, Jul 18, 2012 at 10:49 PM, Laruence <laruence@php.net> wrote:
> Hi: > this is not a new RFC, I proposed it before, but due to my poor > english and improper examples, it didn't get passed.
thanks phidev's good english, he re-wrote the descriptions. thanks
> > This feature introduces list() support in foreach constructs(more > info can be found here: https://wiki.php.net/rfc/foreachlist): > > <?php > $users = array( > array('Foo', 'Bar'), > array('Baz', 'Qux'); > ); > > // Before > foreach ($users as $user) { > list($firstName, $lastName) = $user; > echo "First name: $firstName, last name: $lastName. "; > } > > // After > foreach ($users as list($firstName, $lastName)) { > echo "First name: $firstName, last name: $lastName. "; > } > ?> > > what do you think? personally, I really think it's a good feature. > > what about commit this into trunk(php 5.5) ? > > thanks > > -- > Laruence Xinchen Hui > http://www.laruence.com/
-- Laruence Xinchen Hui http://www.laruence.com/

Laruence

14 years ago
Hi: since I proposed last year, and seems no argu here. so maybe we can just step into the voting phase? thanks On Wed, Jul 18, 2012 at 10:55 PM, Laruence <laruence@php.net> wrote:
> On Wed, Jul 18, 2012 at 10:49 PM, Laruence <laruence@php.net> wrote: >> Hi: >> this is not a new RFC, I proposed it before, but due to my poor >> english and improper examples, it didn't get passed. > thanks phidev's good english, he re-wrote the descriptions. > > thanks >> >> This feature introduces list() support in foreach constructs(more >> info can be found here: https://wiki.php.net/rfc/foreachlist): >> >> <?php >> $users = array( >> array('Foo', 'Bar'), >> array('Baz', 'Qux'); >> ); >> >> // Before >> foreach ($users as $user) { >> list($firstName, $lastName) = $user; >> echo "First name: $firstName, last name: $lastName. "; >> } >> >> // After >> foreach ($users as list($firstName, $lastName)) { >> echo "First name: $firstName, last name: $lastName. "; >> } >> ?> >> >> what do you think? personally, I really think it's a good feature. >> >> what about commit this into trunk(php 5.5) ? >> >> thanks >> >> -- >> Laruence Xinchen Hui >> http://www.laruence.com/ > > > > -- > Laruence Xinchen Hui > http://www.laruence.com/
-- Laruence Xinchen Hui http://www.laruence.com/

Stas Malyshev

14 years ago
Hi!
> since I proposed last year, and seems no argu here. > > so maybe we can just step into the voting phase?
I'd like to know how it works with references. I.e., you can do: foreach($foo as &$bar) What about the list, how would you use that? Also, I'm not sure which use case we're solving here - could you give some examples where this would provide significant benefit?
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Andrew Faulds

14 years ago
If I understand this correctly, this is like what Python let's you do with tuples. It's handy for getting vector components, hostnames and port numbers, etc. (I apologise for the Python comparison, it is just the language where I usually encounter this, and it makes heavy use of foreach-style loops and tuples) On Jul 20, 2012 6:20 PM, "Stas Malyshev" <smalyshev@sugarcrm.com> wrote:

Stas Malyshev

14 years ago
Hi!
> If I understand this correctly, this is like what Python let's you do > with tuples. It's handy for getting vector components, hostnames and > port numbers, etc. (I apologise for the Python comparison, it is just > the language where I usually encounter this, and it makes heavy use of > foreach-style loops and tuples)
There's no need to apologize for Python comparison, Python is not a dirty word :) However, in PHP functions rarely return sets of tuples that can be manageably unpacked by this foreach syntax - usually it's either something like DB result set, which has unpredictable number of values, or one set of values, which doesn't need foreach. That's why I wanted to see a use case where this is beneficial.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Andrew Faulds

14 years ago
Yeah, that's what I realised as I wrote that. PHP functions don't really use tuples etc. very much, unlike Python. That said, now we have short array syntax, and if we add this, perhaps people will use it more. Still, at the moment the usefulness of this is limited. Perhaps destructuring assignment with objects? So o->x and o->y to $a and $b? On Jul 20, 2012 11:28 PM, "Stas Malyshev" <smalyshev@sugarcrm.com> wrote:

Morgan L. Owens

14 years ago
On 2012-07-21 10:28, Stas Malyshev wrote:
> Hi! > >> If I understand this correctly, this is like what Python let's you do >> with tuples. It's handy for getting vector components, hostnames and >> port numbers, etc. (I apologise for the Python comparison, it is just >> the language where I usually encounter this, and it makes heavy use of >> foreach-style loops and tuples) > > There's no need to apologize for Python comparison, Python is not a > dirty word :) However, in PHP functions rarely return sets of tuples > that can be manageably unpacked by this foreach syntax - usually it's > either something like DB result set, which has unpredictable number of > values, or one set of values, which doesn't need foreach. That's why I > wanted to see a use case where this is beneficial. >
The number of values in a DB result set may be unpredictable, but the number of _elements_ in each value shouldn't be - and the list() will be on those elements: foreach($resultset as list($id, $name, $address, $phone)) { .... } (Assuming I don't use array_map instead - $resultset might not be an array.) Incidentally this also touches on something you say later: On 2012-07-21 11:03, Stas Malyshev wrote:
> > IMHO assignment is always more readable than function with magic > unobvious effects. I'd rather always have assignments than scratch my > head each time reading the code - is this the one that modifies the > argument or the one that doesn't? >
I agree fully with this; having functions actually behaving like, well, _functions_ makes it much easier to see what's going on (I don't have to look up the definition of foo($bar) to see whether it's modifying $bar or not). So when I have a function that has a two- or multi-part result then - instead of having one part as the return value and the others by reference - in Python I'd return a tuple. I like what has been done to improve support for functional programming (despite the elephant in the room); I guess that's why I'm cold to the other proposal to graft OO syntax onto non-OO semantics.

Stas Malyshev

14 years ago
Hi!
> The number of values in a DB result set may be unpredictable, but the > number of _elements_ in each value shouldn't be - and the list() will be > on those elements: > > foreach($resultset as list($id, $name, $address, $phone)) > {
One doesn't see this pattern too much and the reason is - what happens if an element is added or the order changes? Is it really guaranteed the elements are always in this order - what if the query is modified to add some other data from other table, etc.? Thus usually people do more of $row['id'] than list($id, ...) = $row. List() is usually too rigid for something as fluid as DB data sets (and with noSQL DBs where there's no fixed schema it'd be even less appropriate).
> So when I have a function that has a two- or multi-part result then - > instead of having one part as the return value and the others by > reference - in Python I'd return a tuple.
PHP functions can return arrays and some do - e.g. pathinfo(). But not all of them. Maybe getting more functions return result sets instead of modifying parameters could be one target of that API refactoring people are talking about. However, in some case - e.g. function returning result and maybe error code - tuple may not be that convenient, in most cases you just want the result, and unpacking tuple (or array in PHP) would be additional complication.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Morgan L. Owens

14 years ago
On 2012-07-21 12:19, Stas Malyshev wrote:
> Hi! > >> So when I have a function that has a two- or multi-part result then - >> instead of having one part as the return value and the others by >> reference - in Python I'd return a tuple. > > PHP functions can return arrays and some do - e.g. pathinfo(). But not > all of them. Maybe getting more functions return result sets instead of > modifying parameters could be one target of that API refactoring people > are talking about. However, in some case - e.g. function returning > result and maybe error code - tuple may not be that convenient, in most > cases you just want the result, and unpacking tuple (or array in PHP) > would be additional complication. >
Oh, I'm talking about my own user functions, not changing any native PHP functionality; things like returning a lat/long pair, or measurement/precision, or - well, pretty much any situation where a function returns an array with a known sequence of elements. If it can happen once (hence the existence of list in the first place) it can happen several times (in the iteration of a loop). Falling back on reference parameters makes it really hard to get at return values functionally: function foo_wrapper($arg) { $t2 = null; $t1 = foo($arg, $t2); // $t2 passed by reference return [$t1, $t2]; }