> On 9 Dec 2014, at 23:07, Josh Watzman <jwatz...@fb.com> wrote:
> 
> Hey internals! A useful feature that Hack picked up in the last few months 
> are "nullsafe calls", a way of propagating failure forward in a series of 
> chained method calls to the end of the whole computation, getting rid of a 
> lot of the boilerplate in the middle. I think the feature would be a good one 
> for PHP as well, so I'm submitting this RFC to add it -- you can see the RFC 
> itself for a full discussion of the motivation for the feature, as well as 
> the feature itself:
> 
> https://wiki.php.net/rfc/nullsafe_calls

Hi again,

I was in favour of this, but upon further thought, I’m not sure I am. I 
remember I also initially liked it in Hack and then lost interest.

First, how is this substantially different from catching an exception? With 
Nikita’s Exceptions in the Engine RFC 
(https://wiki.php.net/rfc/engine_exceptions_for_php7), something like this 
would be possible:

    try {
        return $foo->bar()->qux()->elePHPant()->dance();
    } catch (EngineException $e) {
        return NULL;
    }

That would essentially do the same as what you’re proposing:

    return $foo?->bar()?->qux()?->elePHPant()?->dance();

Are there many instances where there’d be a substantial benefit to using ?-> 
versus catching an exception?

Second, not short-circuiting is rather unintuitive. I think most people would 
expect it to short-circuit. Note that ?? and isset() short-circuit, so this 
would be inconsistent with existing NULL-checking operators. So why, then, are 
you proposing that it should not short-circuit? Is there some obscure case that 
this makes easier? If anything, I’d expect that short-circuiting is the more 
useful behaviour. For example, take the following hypothetical line of code:

    $elePHPantParty->danceClub?->addToDanceFloor($elePHPantPool->remove());

If we have the short-circuiting behaviour, then if $elePHPantParty->danceClub 
is NULL, ->addToDanceFloor isn’t called and an ElePHPant isn’t removed from 
$elePHPantPool. On the other hand, if ->danceClub isn’t NULL, ->addToDanceFloor 
is called and an ElePHPant will be removed from $elePHPantPool.

With the non-short-circuiting behaviour, this code would have to be longer, and 
you couldn’t use ?-> here. Instead, you’d have to write this:

    if ($elePHPantParty->danceClub !== NULL) {
        $elePHPantParty->danceClub->addToDanceFloor($elePHPantPool->remove());
    }

It is, admittedly, a hypothetical scenario, but it does demonstrate why having 
it not short-circuit is less useful. Are there any examples where 
short-circuiting is a problem?

Third, as has already been mentioned, this doesn’t support ?-> for properties, 
which is both unintuitive (people will reasonably expect it to work) and makes 
it a lot less useful, because you won’t always be dealing with method calls. 
While $foo?->bar()?->foobar() might work, what about something like 
$foo?->bar?->foobar(), where one of the links in the chain is a property? This 
is not at all an unlikely scenario.

Finally, this may encourage bad code. As someone helpfully pointed out in the 
reddit discussion (http://redd.it/2ot15u), this encourages breaking the Law of 
Demeter, i.e. that objects should only talk to their immediate friends. 
Usually, long chains of method calls across multiple objects are not a good 
idea, yet the main benefit of this RFC is to reduce the boilerplate needed for 
that scenario. 

I am only one voice in this discussion, but I personally don’t really like this 
RFC.

Thanks!
--
Andrea Faulds
http://ajf.me/





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to