Skip to content

Instantly share code, notes, and snippets.

@Danack

Danack/Words.md Secret

Created August 3, 2020 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Danack/886d7a2bdf3ac96ee2dc4f6534a58e28 to your computer and use it in GitHub Desktop.
Save Danack/886d7a2bdf3ac96ee2dc4f6534a58e28 to your computer and use it in GitHub Desktop.
Words.md

Opening

  • I introduce the podcast (prerecorded), and start with: “This is episode X, about X”, and ask you to introduce yourself?

  • You tell who they are, what you do (work, open source), and you came to contribute to PHP. Please no commercial messages.

Discussion

  • What is a “nullsafe” operator?

Imagine you have a variable that is either going to be an object or could be null. If the variable is an object then you want to call a method on it, and obviously if it's null then you can't call the method on it, as that would give an error.

What the nullsafe operator does is allow you to handle that in a single line, rather than having to have if statements.

  • What problem is this feature going to solve?

Reduce amount of code needed for trivial null checking.

This:

$country = $session?->user?->getAddress()?->country;

is easier to both write and read than this:

$country =  null;
 
if ($session !== null) {
    $user = $session->user;
 
    if ($user !== null) {
        $address = $user->getAddress();
 
        if ($address !== null) {
            $country = $address->country;
        }
    }
}

Although this might appear to be a low value thing, for me it really reduces the amount of cognitive load when reading and maintaining code, as rather than having to parse multiple lines of code and check what it's doing, you can see in a glance that either:

  • this line results in null.
  • or skip to the end of the line to look at the final part.
  • What is the syntax?

Where you have an instance object operator (i.e. a litte arrow) but the object may be null, you can instead use the new nullsafe operator which is ?-> (question mark arrow.

If the left hand part is null then the chain is short-circuited and evaluates to null, and if it's not null then the method call or property access is done as normal.

  • What is short circuiting?

Don't do the rest of this bit of the operation.

  • Which three ways of short circuiting were looked at?

Given this code:

$obj = null;
$obj?->foo(bar())->baz();

The three different ways of doing short-circuiting are:

  1. Short circuiting for neither method arguments nor chained method calls
$tmp = bar();
null->baz();
  • Bar is called, which is bad as in my opinion if the shortcircuiting
  • ->baz is called() which is terrible. Forces people to add nullsafe operators down the chain
  1. Short circuiting for method arguments but not chained method calls
null->baz();

“Call to a member function on null”

  1. Short circuiting for both method arguments and chained method calls

We’ll refer to this as full short circuiting. Neither the function bar() nor the method baz() are called. There will be no “Call to a member function on null” error.

  • Why is full short circuiting the preferred option? (3 points)

  • Do other languages have short circuiting?

Have full short-circuiting: C#, Javascript, Swift, TypeScript

Don't have full short-circuiting: Kotlin, Ruby, Dart, Hack

And it does appear that people who use those languages that lack full short circuiting regret that design choice.

  • Which operators are part of the chain?

Any operators that 'peer' inside the object.

Property access (->) Nullsafe property access (?->) Static property access (::) Method call (->) Nullsafe method call (?->) Static method call (::) Array access ([])

Other operators that don't "look inside the object" e.g. string concatenation or maths operators aren't part of the chain, and so will still happen. Though tbh, this is kind of edge-case, because

echo $data->getMyObject()?->getName() ?? 'no name';
  • What is not possible (write context, references)?

So, up until right before the vote, the RFC was a bit more complicated, and it was possible to use the nullsafe in a write context.

$obj?->bar = 'foo';
$values = [1, 2, 3];
foreach ($values as $foo?->bar) {
  // I did not know you could foreach into
  // a property of an object.
}

echo $foo->bar;
function foo(&$param) {
    $param = 'John';
}

foo($obj?->bar);

Luckily someone pointed out, that this was rubbish, as you can't assign to a possibly-non-existent container.

And so Illier suggested "Why don't we just restrict it to read contexts?" and forget about the write contexts....and

  • So the vote was overwhelmingly in favour. Did you think it was going to be so widely accepted or did you think the vote was going to be closer?

I thought it was going to be a lot closer, and more controversial.

As part of the discussion some people raised a point that while I don't fully agree with, it is something to bear in mind.

They were concerned that people would use this feature in places where having null rather than an object might represent an error and someone might need to figure out why the null is there, which the nullsafe operator doesn't do.

But I think the answer to that is, this feature wouldn't be appropriate to use in those scenarios, so although that concern is valid, just avoid using new features without thinking if they fit your usecase.

  • What’s your favourite new feature in PHP 8?

Improvements in the type system, including both union types, and mixed types.

  • Closing

  • I thank you for coming on explaining

  • You say thanks for being on the show in a flowery language

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment