Re: Re: [RFC] [PRE-VOTE] Union types
| From: | Bob Weinand | Date: | Thu, 02 Jun 2016 17:43:07 +0000 |
| Subject: | Re: Re: [RFC] [PRE-VOTE] Union types | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-93725@lists.php.net to get a copy of this message | ||
> Am 02.06.2016 um 19:33 schrieb Rowan Collins <rowan.collins@gmail.com>:
>
> On 02/06/2016 18:11, Andrea Faulds wrote:
>> That aside, the behaviour the RFC now specifies for how weak typing
>> interacts with union types is frighteningly complicated. I don't see how
>> it could be anything other than that, but the new complexity this
>> introduces to PHP is enough for me to vote against this RFC, even
>> ignoring my other concerns.
>
> That is rather a long-winded set of rules, I agree. I wonder if it's possible for the
> order the union type is defined to be taken into account? That way you could specify the rule thus:
>
> * The type is tested against each type in the union in turn.
> * If weak typing is active, scalar types will be coerced where this would normally be allowed,
> and passed over where a TypeError would be thrown.
> * If strict typing is active, scalar types will be treated the same as non-scalar types, and
> must match precisely.
>
>
> So:
>
> function f(int | float $number) { echo gettype($number); }
> f('10'); // int
>
> function g(float | int $number) { echo gettype($number); }
> g('10'); // float
>
> function h(int | Foo | string) { echo gettype($number); }
> h('10'); // int
> h(new Foo); // object
> h('hello'); // string
>
> function i(string | int) { echo gettype($number); }
> i('10'); // string
> i(10); // string
>
> This last example is the only one that might be a bit surprising - the "| int" in the
> type def is actually doing nothing - but there's always scope for user error.
>
>
> In strict mode, things would be a bit different, because no coercion is allowed:
>
> declare(strict_types=1);
>
> function f(int | float $number) { echo gettype($number); }
> f('10'); // [!] TypeError
>
> function g(float | int $number) { echo gettype($number); }
> g('10'); // [!] TypeError
>
> function h(int | Foo | string) { echo gettype($number); }
> h('10'); // string
> h(new Foo); // object
> h('hello'); // string
>
> function i(string | int) { echo gettype($number); }
> i('10'); // string
> i(10); // int
>
>
> It may be that the implementation makes this prohibitively difficult, but it would certainly be
> easier to document than the rules currently proposed.
>
> Regards,
> --
> Rowan Collins
> [IMSoP]
We had that exact idea relatively early, but it exposes other problems… order suddenly matters.
You cannot just add "a" type and get the expected results.
E.g.
function f(true | string $foo) { ... }
everything except 0, ±0, "0" and "" would now return true. That's totally
WTF. Sure, it's more friendly for people who want to read *rules*. But it is very bad for
intuitivity.
Also:
> function i(string | int) { echo gettype($number); }
> i('10'); // string
> i(10); // string
This. This is especially bad as it has different behaviors in strict and weak mode then. That's
a no-go.
The current way is the only viable one, as far as we discovered.
Bob