[RFC] Cast in foreach

php.internals

Chris Riley

7 years ago
Hi internals, I'd like to propose opening an rfc to make the following syntax legal: foreach($array as (int) $i) {} Which would be functionally equivalent to foreach($array as $i) { $i=(int) $i; } Thoughts? Feedback? ~C

Marco Pivetta

7 years ago
On Thu, Feb 21, 2019 at 1:16 PM Chris Riley <t.carnage@gmail.com> wrote:
> Hi internals, > > I'd like to propose opening an rfc to make the following syntax legal: > > foreach($array as (int) $i) {} > > Which would be functionally equivalent to > > foreach($array as $i) { > $i=(int) $i; > } > > Thoughts? Feedback? > ~C >
What's a scope where this would be a massive win, over a new line with a cast? Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

Kalle Sommer Nielsen

7 years ago
Den tor. 21. feb. 2019 kl. 14.16 skrev Chris Riley <t.carnage@gmail.com>:
> > Hi internals, > > I'd like to propose opening an rfc to make the following syntax legal: > > foreach($array as (int) $i) {}
How would this interact with the foreach-list syntax? $data = [ ["id" => 1, "name" => 'Tom'], ["id" => 2, "name" => 'Fred'], ]; foreach ($data as ["id" => $id, "name" => $name]) { echo "id: $id, name: $name\n"; } Having something like: foreach ($data as (int) ["id" => $id, "name" => $name]) { Would then make both $id and $name integers?
-- regards, Kalle Sommer Nielsen kalle@php.net

Riikka Kalliomäki

7 years ago
On Thu, Feb 21, 2019 at 3:36 PM Kalle Sommer Nielsen <kalle@php.net> wrote:
> > Den tor. 21. feb. 2019 kl. 14.16 skrev Chris Riley <t.carnage@gmail.com>: > > > > Hi internals, > > > > I'd like to propose opening an rfc to make the following syntax legal: > > > > foreach($array as (int) $i) {} > > How would this interact with the foreach-list syntax?
Hi, internals, I would much rather like to see support for something along the lines of, foreach ($foo as ClassName $bar) { $bar->doStuff(); } This could be equivalent of (e.g. for casting, type checking and strict types): foreach ($foo as $bar) { foo($bar); } function foo(ClassName $bar) { $bar->doStuff(); } I feel there is currently significant pain when using iterable pseudotype and generators. It's not possible to indicate in a type safe manner the yield value of a generator nor what a iterable is supposed to be returning. foreach is the structure used (in general) to traverse these and I very often find myself using something like /** @var ClassName $bar */ preceeding the foreach loop just to have some kind of type safety/autocomplete via static analysis. Though, I suppose at least some kind of iterable_apply($iterable, $function) could also solve this. While it would be easy to create in userland, I don't like implementing common small functions to a number of separate libraries. Using the iterable type in PHP is quite painful at the moment, since most internal functions take either a Traversable or an array, but rarely both. Turning an iterable to an indexed array is kinda painful if you want to leverage the internal type decleration functionality: function foo (iterable $ints) { $actualInts = []; foreach ($ints as $int) { $actualStrings = (function (int $int): int { return $int; })($int); } } or function bar (iterable $ints) { $actualInts = (function (int ... $ints): array { return $ints; })(... array_values(is_array($ints) ? $ints : iterator_to_array($ints))); } See, for example: https://3v4l.org/ebRjE In my mind, the support for foreach-list syntax seems less relevant, as if you're passing around arrays with specific keys, then you're probably dealing with more known quantities. At least to me, this is particularly painful issue when writing library code. While typed arrays would also solve some of these issues, you'd still probably have a lot of third party code that would, for example, have untyped return values and you would also still need a way to type generator yield values as well.
-- Riikka Kalliomäki https://github.com/Riimu

Chris Riley

7 years ago
In this instance, I would expect the cast to come before each variable eg foreach ($data as ["id" => (int) $id, "name" => (string) $name]) On Thu, Feb 21, 2019, 13:28 Kalle Sommer Nielsen <kalle@php.net> wrote:

Stas Malyshev

7 years ago
Hi!
> I'd like to propose opening an rfc to make the following syntax legal: > > foreach($array as (int) $i) {} > > Which would be functionally equivalent to > > foreach($array as $i) { > $i=(int) $i; > }
This doesn't seem to add anything to existing functionality - what's wrong with just making explicit cast, so that it's clear what is being done? Traditionally, PHP opts to the side of clarity rather than brevity.
-- Stas Malyshev smalyshev@gmail.com