> 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