On Thu, Apr 16, 2020 at 12:20 PM Enno Woortmann <enno.woortm...@web.de>
wrote:

> Hi together,
>
> as the voting for the "Type casting in array destructuring expressions"
> shows a clear direction to be declined (sad faces on my side, I really
> would've liked it as a feature completion of the casting feature set
> without the need for a really new syntax, as the parser also already
> coverred it, but ok, time to continue :D ), combined with a strong
> interest for the topic "type checks in array destructuring expressions"
> (as well in the discussion as in the vote) I've set up a first draft of
> an RFC covering this topic:
>
> https://wiki.php.net/rfc/typehint_array_desctructuring
>
> The discussion around the casting in array destructuring brought up the
> idea to perform regular type checks in array destructuring expressions.
> This RFC proposes a new syntax to type hint a variable inside an array
> destructuring expression:
>
> $data = [42, 'Example', 2002];
> [int $id, string $data, int $year] = $data;
>
> The type hints behave identically to the type hints used in method
> signatures (compare https://wiki.php.net/rfc/scalar_type_hints_v5). This
> especially includes a behaviour depending on the strict_types directive.
>
> Additionally to scalar type hints also object type hints are possible.
>
> I've not yet started an implementation draft but I think this one will
> be more tricky than the type cast implementation approach. As the parser
> re-uses the array definition for array destructuring expressions (which
> also leads to the type cast implementation without touching the parser)
> adding type hints to the definition would also affect other parts of the
> language eg. something like:
>
> $x = [int $a, string $b];
>
> would be parsed by the parser. I'm currently not able to grasp the
> impact of such a change. But that's another topic.
>
> Let's focus on the idea itself instead of the implementation first.
> Thoughts on the first draft?
>

As you say, this syntax will likely run into parsing issues. Once you take
into account that types aren't just "int", but also "Foo|Bar", and also
consider that we have support for references in unpacking, you could be
left with something like

    [int|float &$foo] = $bar;

Without actually testing, I would expect that this is going to run into
issues of similar difficulty as the arrow function proposal encountered.

Rather than integrating this into the destructuring assignment syntax, I
think it would be more helpful to view this as the infallible variant of
pattern matching, which is also being discussed in the "match expression"
thread. As suggested there, the syntax could be something like

    let [int|float $foo] = $bar;

and would throw if the RHS does not satisfy the pattern on the LHS (unlike
the match variant, which is fallible).

I think this might help to bring things under one umbrella, and to draw a
clearer line between this functionality and typed variables (if it's just a
pattern guard, then it's expected that the type restriction is checked
instantaneous, not enforced persistently.)

Nikita

Reply via email to