Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:79529 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 40055 invoked from network); 10 Dec 2014 17:22:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Dec 2014 17:22:57 -0000 Authentication-Results: pb1.pair.com smtp.mail=ajf@ajf.me; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ajf@ajf.me; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ajf.me designates 198.187.29.245 as permitted sender) X-PHP-List-Original-Sender: ajf@ajf.me X-Host-Fingerprint: 198.187.29.245 imap11-3.ox.privateemail.com Received: from [198.187.29.245] ([198.187.29.245:57018] helo=imap11-3.ox.privateemail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 32/D1-29826-F6188845 for ; Wed, 10 Dec 2014 12:22:56 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.privateemail.com (Postfix) with ESMTP id A7F80880318; Wed, 10 Dec 2014 12:22:45 -0500 (EST) X-Virus-Scanned: Debian amavisd-new at imap11.ox.privateemail.com Received: from mail.privateemail.com ([127.0.0.1]) by localhost (imap11.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 43JINPrX8iJA; Wed, 10 Dec 2014 12:22:43 -0500 (EST) Received: from oa-res-26-240.wireless.abdn.ac.uk (oa-res-26-240.wireless.abdn.ac.uk [137.50.26.240]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.privateemail.com (Postfix) with ESMTPSA id ACC98880110; Wed, 10 Dec 2014 12:19:58 -0500 (EST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.1 \(1993\)) In-Reply-To: <95A581EE-A062-4926-BE44-BCA87FC9B356@fb.com> Date: Wed, 10 Dec 2014 17:19:56 +0000 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <9230CB24-22FC-4A0E-A9D5-F02523B65A02@ajf.me> References: <95A581EE-A062-4926-BE44-BCA87FC9B356@fb.com> To: Josh Watzman X-Mailer: Apple Mail (2.1993) Subject: Re: [PHP-DEV] [RFC] Nullsafe calls From: ajf@ajf.me (Andrea Faulds) > On 9 Dec 2014, at 23:07, Josh Watzman wrote: >=20 > 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: >=20 > https://wiki.php.net/rfc/nullsafe_calls Hi again, I was in favour of this, but upon further thought, I=E2=80=99m 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=E2=80=99s 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=E2=80=99re proposing: return $foo?->bar()?->qux()?->elePHPant()?->dance(); Are there many instances where there=E2=80=99d 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=E2=80=99d 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=E2=80=99t = called and an ElePHPant isn=E2=80=99t removed from $elePHPantPool. On = the other hand, if ->danceClub isn=E2=80=99t 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=E2=80=99t use ?-> here. Instead, you=E2=80=99d = have to write this: if ($elePHPantParty->danceClub !=3D=3D 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=E2=80=99t support ?-> = for properties, which is both unintuitive (people will reasonably expect = it to work) and makes it a lot less useful, because you won=E2=80=99t = 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.=20 I am only one voice in this discussion, but I personally don=E2=80=99t = really like this RFC. Thanks! -- Andrea Faulds http://ajf.me/