Hi internals
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operator
It introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.
Let me know what you think.
Ilija
It introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.
I like it a lot! Concise and clear RFC.
From having used a similar feature in TypeScript I can say it is quite
convenient, easy to get used to and makes for much leaner code.
IMO not having it on array accesses isn't so bad as with arrays you can
easily isset($deep['into']['the']['array']) in one go, while with
objects and getters etc it tends to lead to much uglier and repetitive
code like:
if ($foo && $foo->getBar() && $foo->getBar()->getBaz()) { ... }
So yeah, +1
Best,
Jordi
--
Jordi Boggiano
@seldaek - https://seld.be
Hi internals
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operatorIt introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.Let me know what you think.
The semantics look reasonable to me, but I'd recommend including some
discussion on the rationale behind the short-circuiting behavior in the
RFC. That is, what the options are, and why this is the best option (which
is not the option that the previous RFC on this topic picked). It would
also be nice to cross-reference semantics of ?-> in other languages that
have it, to make sure we don't introduce any unexpected WTFs for people
switching between languages. I think the specified behavior is consistent
with what everyone else does, but I haven't checked to be sure.
Regards,
Nikita
Hi Nikita
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operatorThe semantics look reasonable to me, but I'd recommend including some
discussion on the rationale behind the short-circuiting behavior in the
RFC. That is, what the options are, and why this is the best option (which
is not the option that the previous RFC on this topic picked). It would
also be nice to cross-reference semantics of ?-> in other languages that
have it, to make sure we don't introduce any unexpected WTFs for people
switching between languages. I think the specified behavior is consistent
with what everyone else does, but I haven't checked to be sure.
Thanks for your feedback. I added a short analysis of the most popular
programming languages as well as a list of benefits and drawbacks of
short circuiting.
We might still go into detail on what the languages that do short
circuiting consider part of the chain. If it doesn't clutter the RFC
too much I will do that.
Ilija
Hi internals
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operatorIt introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.Let me know what you think.
Ilija
Hi Internals,
Wouldn't it make more sense to make isset
smarter? So that it can
handle these situations just like it would with array access. That
way you could use the null coalescing operator as well.
I don't see many situations where you would be selective in which
method in the chain you would want to make nullsafe and which ones you
wouldn't. I think it would mostly be the entire chain, in which case
using ??
would be much less verbose. In the few cases where you
want to be specific in which are nullsafe and which ones aren't you
can introduce one more variable.
Using the first example in the RFC this would visully be far nicer and
more readable about the intent:
$country = $session->user->getAddress()->country ?? null;
Besides, shouldn't the example really be:
$user->getAddressCountry();
I don't recall ever having to nest three levels like that example. I
know the example is contrived, but wouldn't you know if you have a
logged in user or not? Then just have a simple getter on the user for
what you need to check. Chances are those variables you're trying to
save will be used elsewhere, or if not, refactor.
Also, assuming we have control over the User class, you can either
make address a property or use the magic getters (that many frameworks
have, love or hate them). Even the new new accepted Constructor
Property Promotion would be helpful in facilitating that. Basically
we can easily get around this problem already, and some frameworks do
it by default. If not, writing one getter where you have to check a
few things is IMO far nicer than a long chain of possibly null
objects.
This is how I would solve the issue, assuming we're just in the
controller we don't make anything specifically for the User or Address
classes and no other uses for those specifically are needed.
protected function getCountry()
{
$user = $this->session->user ?? null;
if ($user === null)
$this->redirectToLogin();
if ($user->getAddress() === null)
return null;
return $user->getAddress()->country ?? null;
}
Chaining that many objects together that may or may not be null just
seems so wrong to me.
My concern is that we would start seeing ?->
far too often and it
would promote some lazy habits, because people would add it "just in
case". Personally I think it should be more explicit when we are
null-checking, and since the ->
object access usually doesn't have
spaces around it, it could "muddy the water".
It reminds me too much of the proposed "unary null coalescing
operator", which also reminds me of the error control operator. Maybe
make the syntax ->@
to be more clear?
Sorry if I come off a bit harsh, but I don't see the need for this as
other solutions to this problem are more favourable IMHO. As much as
it can be annoying sometimes, the Call to a member function foo() on null
is a very useful error.
Thanks,
Peter
Hi Peter
Wouldn't it make more sense to make
isset
smarter? So that it can
handle these situations just like it would with array access. That
way you could use the null coalescing operator as well.
Both of those are valid approaches. I do prefer the ?-> operator for
two reasons.
- ?? is more error prone (e.g. you won't get an error if a variable
or property is undefined) - You can see immediately which sub-expressions can be null and which
cannot (or rather must not)
That is not to say that there aren't also benefits to ??
- No new syntax to learn
- You can see more clearly where the short circuiting chain ends
I don't see many situations where you would be selective in which
method in the chain you would want to make nullsafe and which ones you
wouldn't.
IMO you should only use ?-> exactly where you expect null values.
Using ?? would ignore null (as well as undefined) everywhere in any
sub-expression even if unexpected.
I don't recall ever having to nest three levels like that example.
I agree. Take the example with a grain of salt. It's hard to come up
with a relatable, meaningful, short example.
Sorry if I come off a bit harsh, but I don't see the need for this as
other solutions to this problem are more favourable IMHO.
Not in the slightest. That's why it's called a "request for feedback"
and not "request for praise", you're free to disagree :)
As much as it can be annoying sometimes, the
Call to a member function foo() on null
is a very useful error.
Absolutely. To clarify: The idea is not to sprinkle ?-> everywhere.
Only use ?-> when null is an expected and acceptable value.
Ilija
BIG THUMBS UP for this feature.
As was mentioned that TypeScript uses this and saves developers lots of
time by avoiding nested null checking.
I suggest in the RFC including a list of other languages that have this
feature.
Hi internals
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operatorIt introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.Let me know what you think.
Ilija
Hi internals
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operator
I've reworded some things and added more information on short
circuiting. Functionality wise the RFC has remained the same.
Since there was little negative feedback I'd like to put this feature
to a vote in ~1 week. If you have any concerns or criticism please let
me know in time.
Ilija
I've reworded some things and added more information on short
circuiting. Functionality wise the RFC has remained the same.Since there was little negative feedback I'd like to put this feature
to a vote in ~1 week. If you have any concerns or criticism please let
me know in time.
Just curious, do you plan on putting this to a vote in near time? The
feature freeze is coming soon.
Just curious, do you plan on putting this to a vote in near time? The
feature freeze is coming soon.
There's a remaining complication with references which I had limited
time to work on. This doesn't technically need to be fixed to start
the vote but if it can't be solved reasonably it would have to be
described in the RFC which is why I'm hesitant.
I'll invest some time over the next few days so that I can hopefully
start the vote by the end of the week. If I can't find a solution I
might delay the RFC for PHP 8.1.
Ilija
Hi internals
There's a remaining complication with references which I had limited
time to work on. This doesn't technically need to be fixed to start
the vote but if it can't be solved reasonably it would have to be
described in the RFC which is why I'm hesitant.
I updated the RFC to disallow using the nullsafe operator in
expressions passed by reference. This solves the last remaining
(known) issue. If there are no objections I'd like to start the vote
on Tuesday, 2020-07-14.
Ilija
Hi internals
I updated the RFC to disallow using the nullsafe operator in
expressions passed by reference. This solves the last remaining
(known) issue. If there are no objections I'd like to start the vote
on Tuesday, 2020-07-14.
I have actually made one more change to the RFC. Trying to take the
reference of a nullsafe chain is now always an error (at compile time
when possible, otherwise at runtime). Because of this change I'll
postpone the vote until tomorrow.
Ilija
Hi internals
Unfortunately, we have found some new edge cases that are currently
not handled. I will have to delay the vote again. Over the next day or
two I will implement the changes and see if there are any other
surprises. If there are, I will be delaying the RFC to PHP 8.1. Sorry
:(
Ilija
Hi internals
Unfortunately, we have found some new edge cases that are currently
not handled.
So, we've decided to completely disallow the nullsafe operator in
write context. This means you can no longer use it on the left hand
side of an assignment. This change was made mostly due to technical
issues but some of the semantics were also not completely clear (e.g.
do we always execute the right hand side? which order? etc).
You can find a diff of the changes here:
https://github.com/iluuu1994/nullsafe-operator-rfc/compare/5df9d041d2d202e5fab02b5881f2c4dc1fd9bcce...v1
I realize that it's very much last-minute but I will be opening the
vote tomorrow unless there are any objections. This way we have a few
days to merge before the feature freeze if the RFC is accepted.
Ilija
Hi Ilija,
I'd like to introduce another RFC I've been working on:
https://wiki.php.net/rfc/nullsafe_operatorIt introduces the nullsafe operator ?-> that skips null values when
calling functions and fetching properties. In contrast to the last few
attempts this RFC includes full short circuiting.
Would this still work together with short-circuiting and the null
coalesce operator?
I just didn't see a clear example about this but also figured that could
be a practical way to use this:
$country = $session?->user?->getAddress()?->country ?? 'defaultCountry';
(hope the example is readable, my MUA insists on wrapping the lines)
thanks,
- Markus
Hi Markus
Would this still work together with short-circuiting and the null
coalesce operator?$country = $session?->user?->getAddress()?->country ?? 'defaultCountry';
Yes, your example will still work, this is solely about references :)
Ilija
Hi,
Would this still work together with short-circuiting and the null
coalesce operator?$country = $session?->user?->getAddress()?->country ?? 'defaultCountry';
Yes, your example will still work, this is solely about references :)
Thanks for clarifying, that's fantastic :)
- Markus
Den 2020-07-14 kl. 10:51, skrev Ilija Tovilo:
Hi Markus
https://wiki.php.net/rfc/nullsafe_operator
Would this still work together with short-circuiting and the null
coalesce operator?$country = $session?->user?->getAddress()?->country ?? 'defaultCountry';
Yes, your example will still work, this is solely about references :)Ilija
When I see this I come to think about if this might have helped
with upgrading to PHP 7 from PHP 5 due to the RFC:
Like:
$value = $countvalue?->count($countvalue);
Even if I solved over 90% replacing count with empty there could
be a few more places where this might prove handy. So +1 on this!
r//Björn L