Without type annotations:

function foo($b) {

if (!is_string($b)) {

// Ugh, why can't the language enforce this?

throw new Exception("needed a string");

}

}


With type annotations:

function foo(string $b) {

// I know $b is a string. I don't need to check. :)

}


Without unions:

function foo($b) {
    if (is_string($b)) {
        // ...
    } else if ($b instanceof Bar) {
        // ...

    } else {

   // Ugh, why can't the language enforce this?

        throw new Exception("needed a string|Bar");

    }

}


With unions:

function foo(Bar|string $b) {

    if (is_string($b)) {
        // ...
    } else {
        // I know $b is a Bar here. I don't need to check. :)
    }
}


In both cases, the type annotation has removed the 1 check and the need to
throw an exception. It's the exact same benefit.


On Sat, Apr 16, 2016 at 1:10 AM, Andrea Faulds <a...@ajf.me> wrote:

> Hi Stas,
>
> Stanislav Malyshev wrote:
>
>> I don't know what is complicated about "string|Stringable" or "Foo|Bar"
>>> since it is super self-explanatory. However, I find myself checking the
>>>
>>
>> It may be self-explanatory for you. It's much less self-explanatory for
>> somebody just starting to learn. It is also very dangerous - if it's
>> either Foo or Bar, can you call Foo::stuff on it or not? If it's string
>> or not string, can you call strlen on it? Etc., etc. It adds a lot of
>> cognitive load and complicates the whole picture. You may have a
>> specific use case where it is useful (which we have yet to see btw) but
>> please remember it's a language with literally millions of use cases and
>> users.
>>
>
> This is something that particularly concerns me about union types, in that
> they reduce type safety. If you have a union type of Foo|Bar for some
> variable, then the set of methods you can call on that variable is actually
> the intersection, not the union, of the set of methods you can call on Foo
> and Bar. Which, unless those two classes share some interface, is probably
> an empty set. So there's nothing you can actually do safely with it without
> doing checks within the body of the function, and if you're doing that,
> then why do we have a type declaration? It's only barely more useful than
> omitting a type declaration at all; type declarations are supposed to
> prevent you needing to check. On the other hand, if the two classes share
> some methods, then either there's an interface you can already use here, or
> you can create one. Either way, you don't need a union type.
>
> There are some cases where you can't create an interface, but if that's
> the case, I think it is more worthwhile to look at how we can fix those
> cases, rather than add what amounts to a hacky workaround.
>
> Thanks!
> --
> Andrea Faulds
> https://ajf.me/
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to