Re: [PHP-DEV] [RFC] [DISCUSSION] Type casting in array destructuringexpressions

This is only part of a thread. view whole thread
  109333
March 26, 2020 12:38 enno.woortmann@web.de (Enno Woortmann)
Hi Levi,

Am 25.03.2020 um 21:44 schrieb Levi Morrison:
> To me, this is almost a good idea. However, I would want regular type > checking, not casts. Importantly, regular type checks would fit well > on allowing array destructuring directly in function signatures, which > would basically be a form of named parameters.
How exactly do you imagine array destructuring in function signatures with type checks? Something like: function test(['parameter1' => int $parameter1, 'parameter2' => string $parameter2) {     // ... do something with $parameter1 and $parameter2 } Calling the function then may look like: test(['parameter1' => 100, 'parameter2' => 'Hello World']); I guess the type check then depends on the strict_types direcitve whether a call like: test(['parameter1' => 100, 'parameter2' => 100]); would trigger a TypeError or be valid and cast the value for $parameter2 to a string just like a casual function signature with a string parameter. The same behaviour would be applied to array destructuring outside of function signatures. Assumed we gather data from a CSV file: 1,Test,2002 2,Example,2010 3,Demo,2016 And we want to process the data with array destructuring like: $handle = fopen('test.csv', 'r'); while (($data = fgetcsv($handle)) !== false) {     [int $id, string $data, int $year] = $data;     // do something with the correctly typed variables } The code would trigger a fatal error when strict_types are enabled. With strict_types disabled it would behave identically as the currently proposed casts. I wouldn't want the example above to trigger a TypeError even when strict_types are enabled. As a form of named parameters regular type checks should definitely preferred over a cast but for the current usage of array destructuring I think regular type checks cover different use cases (which may also exist) than my proposal. Enno
  109334
March 26, 2020 12:49 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 26 Mar 2020 at 12:39, Enno Woortmann woortmann@web.de> wrote:

> > $handle = fopen('test.csv', 'r'); > while (($data = fgetcsv($handle)) !== false) { > [int $id, string $data, int $year] = $data; > // do something with the correctly typed variables > } > > The code would trigger a fatal error when strict_types are enabled. With > strict_types disabled it would behave identically as the currently > proposed casts. >
As I mentioned in a previous e-mail, if it followed current strict_types=0 semantics, it would error if the input row was something like "42,hello,not-a-valid-year". Following standard cast semantics, that input would instead silently give you a value of 0 in $year, which is often not what you want. Regards, -- Rowan Tommins [IMSoP]
  109354
March 26, 2020 19:49 enno.woortmann@web.de (Enno Woortmann)
>> $handle = fopen('test.csv', 'r'); >> while (($data = fgetcsv($handle)) !== false) { >> [int $id, string $data, int $year] = $data; >> // do something with the correctly typed variables >> } >> >> The code would trigger a fatal error when strict_types are enabled. With >> strict_types disabled it would behave identically as the currently >> proposed casts. >> > > As I mentioned in a previous e-mail, if it followed current strict_types=0 > semantics, it would error if the input row was something like > "42,hello,not-a-valid-year". > > Following standard cast semantics, that input would instead silently give > you a value of 0 in $year, which is often not what you want.
Hi Rowan, I liked your idea of strict casts which would increase the possibilities of casting in general but also improve casting while array destructuring. Let's have a look at various combinations. The current proposal (behaviour doesn't depend on strict_types): [(int) $id, (string) $data, (int) $year] = $data; "42,hello,2020" --> Works as expected, everything fine "42,hello,not-a-valid-year" --> results silently in a 0. May not be wanted, as you describe, but in my opinion that's fine as it's the current casting behaviour Extending the proposal with strict castings (behaviour doesn't depend on strict_types): [(!int) $id, (!string) $data, (!int) $year] = $data; "42,hello,2020" --> Works as expected, everything fine as "2020" can be casted to an int "42,hello,not-a-valid-year" --> Results in a TypeError as the year can't be casted to an int Using regular type checks (depends on strict_typed): declare(strict_types=0); [int $id, string $data, int $year] = $data; "42,hello,2020" --> Works as expected, everything fine as the id with "42" and the year with "2020" can be casted to an int "42,hello,not-a-valid-year" --> Results in a TypeError as the year can't be casted to an int declare(strict_types=1); [int $id, string $data, int $year] = $data; "42,hello,2020" --> Results in a TypeError as id and year are both strings "42,hello,not-a-valid-year" --> Results in a TypeError as id and year are both strings My favourite behaviour would be the one described for strict castings/regular type checks with strict_types disabled. But I don't like the idea it's only usable without strict_types to get the casting-feature intended by the RFC. Cheers, Enno