# Nullsafe

- Thread: https://externals.io/message/112159
- Original archive: https://news-web.php.net/php.internals/112159
- Started by Eugene Sidelnyk on 2020-11-03T16:38:02+00:00
- Messages: 23
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #112159 — Eugene Sidelnyk — 2020-11-03T16:38:02+00:00

URL: https://externals.io/message/112159#112159

Hello, internals!
I am wondering why don't we use ordinary `->` operator with safe null
handling? Programmers will be more prone to return null values. And thus,
in most of cases `?->` will replace `->`.
Why do we need another operator, if we can implement null safe in current
operator without BC breaks?

---

## #112160 — Benjamin Morel — 2020-11-03T16:48:12+00:00

URL: https://externals.io/message/112159#112160 · In reply to: #112159

> I am wondering why don't we use ordinary `->` operator with safe null
> handling?


Hi,

- changing the current behaviour of `->` would be a huge BC break
- and if we need another reason, there are many situations where you do
want to fail early if the left operand is null, so the current operator is
a good fit

— Benjamin

---

## #112161 — G. P. B. — 2020-11-03T18:33:20+00:00

URL: https://externals.io/message/112159#112161 · In reply to: #112160

On Tue, 3 Nov 2020 at 16:48, Benjamin Morel <benjamin.morel@gmail.com>
wrote:

> 
>
> > […]
>

Implicit nullable is terrible, moreover I don't see why users should return
null values more often.
They serve their purpose but most of the time you can use another sane/safe
default of the given
property type.

Moreover, I don't see the issue with another operator as it conveys *clear*
intent especially in
PHP as everything is `null` by default (might warn but still).

*Technically* this isn't a BC break, but it's an enormous change of
semantics for something
which is worse IMHO. Also the operator has already been voted on, accepted,
and implemented.

Regards,

George P. Banyard

---

## #112162 — G. P. B. — 2020-11-03T19:09:34+00:00

URL: https://externals.io/message/112159#112162

> 
>
> > […]
> First of all please bottom post instead of top posting.
>
> Secondly, that's just your philosophy and the null safe operator was
> introduced to
> accommodate this way of thinking.
> However, this does not mean it's better or should be the way it works,
> especially now
> that the null safe operator has already been implemented, and changed
> established
> semantics need a *good* reason.
>
> Regards,
>
> George P. Banyard
>


Just saw that you replied individually, please keep all discussion on list
(i.e. reply all).

Regards,

George P. Banyard

---

## #112163 — Eugene Sidelnyk — 2020-11-03T19:18:20+00:00

URL: https://externals.io/message/112159#112163

---------- Forwarded message ---------
From: Eugene Sidelnyk <zsidelnik@gmail.com>
Date: Tue, Nov 3, 2020 at 7:08 PM
Subject: Re: [PHP-DEV] Nullsafe
To: Benjamin Morel <benjamin.morel@gmail.com>


But currently working code doesn't fail with NullPointerException?
Otherwise it would not be a working code.
Early fail will be when we try return / pass anywhere this value

On Tue, Nov 3, 2020, 6:48 PM Benjamin Morel <benjamin.morel@gmail.com>
wrote:

> 
>
> > […]
>
>
> Hi,
>
> - changing the current behaviour of `->` would be a huge BC break
> - and if we need another reason, there are many situations where you do
> want to fail early if the left operand is null, so the current operator is
> a good fit
>
> — Benjamin

---

## #112165 — Eugene Sidelnyk — 2020-11-03T19:18:40+00:00

URL: https://externals.io/message/112159#112165

On Tue, Nov 3, 2020, 7:58 PM Benjamin Morel <benjamin.morel@gmail.com>
wrote:

> Hi,
>
> It currently returns null but issues a warning (which can be, and often
> is, converted to an exception by frameworks / custom error handlers):
> https://3v4l.org/1ZkVC
>
> The new operator returns null with no warning:
> https://3v4l.org/Wmun4
>
> Benjamin
>
> 
>
> > […]

---

## #112166 — Eugene Sidelnyk — 2020-11-03T19:18:57+00:00

URL: https://externals.io/message/112159#112166

---------- Forwarded message ---------
From: Eugene Sidelnyk <zsidelnik@gmail.com>
Date: Tue, Nov 3, 2020 at 8:11 PM
Subject: Re: [PHP-DEV] Nullsafe
To: Benjamin Morel <benjamin.morel@gmail.com>


When trying call a method, php falls with fatal error:
https://3v4l.org/jk5Fp

With nullsafe it silently returns null:
https://3v4l.org/MhXtM

Are there cases when we would like to use ordinary operator rather then
nullsafe? In my opinion by default it should be safe

On Tue, Nov 3, 2020, 7:58 PM Benjamin Morel <benjamin.morel@gmail.com>
wrote:

> Hi,
>
> It currently returns null but issues a warning (which can be, and often
> is, converted to an exception by frameworks / custom error handlers):
> https://3v4l.org/1ZkVC
>
> The new operator returns null with no warning:
> https://3v4l.org/Wmun4
>
> Benjamin
>
> 
>
> > […]

---

## #112167 — Eugene Sidelnyk — 2020-11-03T19:19:20+00:00

URL: https://externals.io/message/112159#112167

---------- Forwarded message ---------
From: Eugene Sidelnyk <zsidelnik@gmail.com>
Date: Tue, Nov 3, 2020 at 9:05 PM
Subject: Re: [PHP-DEV] Nullsafe
To: G. P. B. <george.banyard@gmail.com>


Null value by itself was invented to indicate lack of data.
But we can't just use it instead of objects, because of how it works.
We need to create a boilerplate of NullObjects.
Consider the abstract factory example:
https://3v4l.org/9D9LU

The problem is not with nullsafe operator. It is basically in null
constant. To correctly work with absence of object, NullObjects is required
(one for each abstraction).

> I don't see why users should return null values more often.

They should not return null values! But with nullsafe they will be prone to.




> On Tue, 3 Nov 2020 at 16:48, Benjamin Morel <benjamin.morel@gmail.com>
> wrote:
>
> > […]
>
> Implicit nullable is terrible, moreover I don't see why users should
> return null values more often.
> They serve their purpose but most of the time you can use another
> sane/safe default of the given
> property type.
>
> Moreover, I don't see the issue with another operator as it conveys
> *clear* intent especially in
> PHP as everything is `null` by default (might warn but still).
>
> *Technically* this isn't a BC break, but it's an enormous change of
> semantics for something
> which is worse IMHO. Also the operator has already been voted on,
> accepted, and implemented.
>
> Regards,
>
> George P. Banyard

---

## #112168 — Eugene Sidelnyk — 2020-11-03T19:19:42+00:00

URL: https://externals.io/message/112159#112168

---------- Forwarded message ---------
From: G. P. B. <george.banyard@gmail.com>
Date: Tue, Nov 3, 2020 at 9:08 PM
Subject: Re: [PHP-DEV] Nullsafe
To: Eugene Sidelnyk <zsidelnik@gmail.com>




> Null value by itself was invented to indicate lack of data.
> But we can't just use it instead of objects, because of how it works.
> We need to create a boilerplate of NullObjects.
> Consider the abstract factory example:
> https://3v4l.org/9D9LU
>
> The problem is not with nullsafe operator. It is basically in null
> constant. To correctly work with absence of object, NullObjects is required
> (one for each abstraction).
>
> > […]
>
> They should not return null values! But with nullsafe they will be prone
> to.
>
>
First of all please bottom post instead of top posting.

Secondly, that's just your philosophy and the null safe operator was
introduced to
accommodate this way of thinking.
However, this does not mean it's better or should be the way it works,
especially now
that the null safe operator has already been implemented, and changed
established
semantics need a *good* reason.

Regards,

George P. Banyard

---

## #112169 — Eugene Sidelnyk — 2020-11-03T19:35:40+00:00

URL: https://externals.io/message/112159#112169 · In reply to: #112161

About implemented, there were many implemented features, but not accepted.
I was very frustrated, when I knew that PHP could have
https://wiki.php.net/rfc/userspace_operator_overloading , and it was
already implemented.
But some people vote down, because they are "narrow-minded" and "have bad
preconceptions" and would like to find more things they like about the
feature.




> On Tue, 3 Nov 2020 at 16:48, Benjamin Morel <benjamin.morel@gmail.com>
> wrote:
>
> > […]
>
> Implicit nullable is terrible, moreover I don't see why users should
> return null values more often.
> They serve their purpose but most of the time you can use another
> sane/safe default of the given
> property type.
>
> Moreover, I don't see the issue with another operator as it conveys
> *clear* intent especially in
> PHP as everything is `null` by default (might warn but still).
>
> *Technically* this isn't a BC break, but it's an enormous change of
> semantics for something
> which is worse IMHO. Also the operator has already been voted on,
> accepted, and implemented.
>
> Regards,
>
> George P. Banyard

---

## #112170 — Dan Ackroyd — 2020-11-03T19:53:08+00:00

URL: https://externals.io/message/112159#112170 · In reply to: #112169

> But some people vote down, because they are "narrow-minded" and "have bad
> preconceptions" and would like to find more things they like about the
> feature.

Please don't call people names.

People vote based on their own choice, and yes sometimes people
disagree on whether something is good or bad.

If nothing else, people are unlikely to take the time to explain the
basis of their choice to you, if they see that it's likely to result
in being called names.

cheers
Dan
Ack

---

## #112171 — Claude Pache — 2020-11-03T19:56:33+00:00

URL: https://externals.io/message/112159#112171 · In reply to: #112159

> Le 3 nov. 2020 à 17:38, Eugene Sidelnyk <zsidelnik@gmail.com> a écrit :
> 
> Hello, internals!
> I am wondering why don't we use ordinary `->` operator with safe null
> handling? Programmers will be more prone to return null values. And thus,
> in most of cases `?->` will replace `->`.
> Why do we need another operator, if we can implement null safe in current
> operator without BC breaks?

Hi,

In a parallel world where people never commit bugs, yes, this is reasonable semantics.

However, it happens more than once that a null value occurs by accident where an object is expected by the programmer. In this case, I very much prefer to have a Warning or an Error, typically handled by an error handler which sends a bug report to the developer, then triggers an emergency stop. That makes it much easier to locate and fix bugs.

Of course, this debuggability facility have to be balanced with the inconvenience to having to write more code in cases where a null value is expected. Having to write “?->” instead of “->” in those cases is a minimal inconvenience. Here, I mean “minimal” in a very literal way: exactly one character of difference.

Also, there is the following benefit: When I write “->”, I am stating that the LHS value should never be null; when I write “?->”, I am stating that I expect that the LHS is sometimes null. Thus, my code is documented in a very concise way (between zero and one character), which is an aid for any future reader (including myself).

Aside: The name “nullsafe” is misleading. The operator is not about safety, it is about handling null values in a concise way. In fact, in some circumstances, sweeping an unexpected null value under the rug may be totally unsafe.

—Claude

---

## #112172 — kocsismate90@gmail.com — 2020-11-03T20:02:42+00:00

URL: https://externals.io/message/112159#112172 · In reply to: #112170

> > […]
>

I think these words are quoted from a comment of mine on the operator
overloading RFC (or a surprising coincidence). This was a mistake on my
part, sorry for that.

Regards,
Máté

---

## #112173 — Marco Pivetta — 2020-11-03T20:10:54+00:00

URL: https://externals.io/message/112159#112173 · In reply to: #112159

Heya,



> Hello, internals!
> I am wondering why don't we use ordinary `->` operator with safe null
> handling? Programmers will be more prone to return null values. And thus,
> in most of cases `?->` will replace `->`.
> Why do we need another operator, if we can implement null safe in current
> operator without BC breaks?
>

Overall, "null safe" can be very dangerous if made the default.

Here's a scenario where I'd never want "null safe" behaviour (which does
anything but introducing safety):

```php
$accounts->get($receiver)
    ->addFunds(
        $accounts->get($sender)
            ->detractFunds($amount)
    );
```

In the above scenario, if the first `$accounts->get()` call returns `null`
for any reason, you may actually destroy money (funds detracted, but never
added to another account).

The example is simplistic, but it shows that "null safe" is everything but
"safe", and it must instead be used only where it absolutely makes sense to
suppress null reference errors.

Similar behaviour can be observed around cast operators, which are too lax
for most businesses logic:
https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229

Safe = crashes when it should crash.

---

## #112175 — Ilija Tovilo — 2020-11-03T21:09:33+00:00

URL: https://externals.io/message/112159#112175 · In reply to: #112173

Hey,


> Overall, "null safe" can be very dangerous if made the default.
>
> Here's a scenario where I'd never want "null safe" behaviour (which does
> anything but introducing safety):
>
> ```php
> $accounts->get($receiver)
>     ->addFunds(
>         $accounts->get($sender)
>             ->detractFunds($amount)
>     );
> ```
>
> In the above scenario, if the first `$accounts->get()` call returns `null`
> for any reason, you may actually destroy money (funds detracted, but never
> added to another account).
>
> The example is simplistic, but it shows that "null safe" is everything but
> "safe", and it must instead be used only where it absolutely makes sense to
> suppress null reference errors.
>
> Similar behaviour can be observed around cast operators, which are too lax
> for most businesses logic:
> https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229
>
> Safe = crashes when it should crash.

I agree. The goal here is not to never encounter a crash. The goal is
to make dealing with known potential null values easier. Crashing is
the safer behavior when something happens you might not have taken
into account.

Honestly, in hindsight "nullsafe" might not have been the best term. I
adopted the term from the previous RFC. There are actually quite a few
other languages that use the word "safe" for this feature.

https://en.wikipedia.org/wiki/Safe_navigation_operator

The most obvious alternative would be optional chaining. I'd suggest
renaming it but I don't think that's viable at this point because
those token names might already be used in various tools and
extensions.

Ilija

---

## #112177 — Eugene Sidelnyk — 2020-11-04T04:37:56+00:00

URL: https://externals.io/message/112159#112177 · In reply to: #112173

Hm, yes. If the `get()` method can return `null`, then it is a problem.
Currently `null` is abused to indicate that value was not found.
`NotFoundException` should be thrown instead.

But.. yeah, we can't just use `nullsafe` by default because of abuse of
`null`.



> Heya,
>
> 
>
> > […]
>
> Overall, "null safe" can be very dangerous if made the default.
>
> Here's a scenario where I'd never want "null safe" behaviour (which does
> anything but introducing safety):
>
> ```php
> $accounts->get($receiver)
>     ->addFunds(
>         $accounts->get($sender)
>             ->detractFunds($amount)
>     );
> ```
>
> In the above scenario, if the first `$accounts->get()` call returns `null`
> for any reason, you may actually destroy money (funds detracted, but never
> added to another account).
>
> The example is simplistic, but it shows that "null safe" is everything but
> "safe", and it must instead be used only where it absolutely makes sense to
> suppress null reference errors.
>
> Similar behaviour can be observed around cast operators, which are too lax
> for most businesses logic:
> https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229
>
> Safe = crashes when it should crash.

---

## #112178 — Eugene Sidelnyk — 2020-11-04T04:42:31+00:00

URL: https://externals.io/message/112159#112178 · In reply to: #112171

However, `null` value is not a good way to use a default value instead of
an object.
When it comes to polymorphism, we would like to avoid null checks from
being all around.
The same goes not only for `->`, but also return / argument type-hintings.

Why do we even need to know that object can be null? Null is just a special
case (there may be other special cases).
Does my customer code need to know about all special cases? Apparently not.
But still, we create another operator to handle this case.
It is ok when it comes to third-party libraries we don't have control over
and sometimes it could return null.

Yet this approach doesn't solve the primary problem. Polymorphism.

You can argue that `null` can be used to indicate that something was not
found.
But this is not the case for returning null. Here an exception should be
thrown.

When I would like to return some default value of an object, it can't just
be null (because it will pile up the code with ? signs).
I need to create a separate NullObject, which implements a particular
interface used at runtime, and return it's instance.
If an interface declares a returning object, then I have to write even more
boilerplate code for those objects.
It is all for such thing as the default "null" value for an object.

IMHO, simple things should be done in a simple way.
What I currently see is that to do a simple thing, I need to create `N`
`null`-classes, whose methods will eventually return `""` or `0` or `0.0`
or `false` or `[]` - generally speaking `null`.



>
>
> > […]
>
> Hi,
>
> In a parallel world where people never commit bugs, yes, this is
> reasonable semantics.
>
> However, it happens more than once that a null value occurs by accident
> where an object is expected by the programmer. In this case, I very much
> prefer to have a Warning or an Error, typically handled by an error handler
> which sends a bug report to the developer, then triggers an emergency stop.
> That makes it much easier to locate and fix bugs.
>
> Of course, this debuggability facility have to be balanced with the
> inconvenience to having to write more code in cases where a null value is
> expected. Having to write “?->” instead of “->” in those cases is a minimal
> inconvenience. Here, I mean “minimal” in a very literal way: exactly one
> character of difference.
>
> Also, there is the following benefit: When I write “->”, I am stating that
> the LHS value should never be null; when I write “?->”, I am stating that I
> expect that the LHS is sometimes null. Thus, my code is documented in a
> very concise way (between zero and one character), which is an aid for any
> future reader (including myself).
>
> Aside: The name “nullsafe” is misleading. The operator is not about
> safety, it is about handling null values in a concise way. In fact, in some
> circumstances, sweeping an unexpected null value under the rug may be
> totally unsafe.
>
> —Claude

---

## #112179 — Eugene Sidelnyk — 2020-11-04T04:59:34+00:00

URL: https://externals.io/message/112159#112179 · In reply to: #112173

But wait!

In your example, funds won't get detracted. If `$accounts->get($receiver)`
will return `null`, then everything inside `addFunds(...)` will not be
executed.
Your example (simplified): https://3v4l.org/38Dk3

Another one:
```php
function expensive_function() {
    var_dump(__FUNCTION__);
}

$foo = null;

$foo?->baz(expensive_function());
```



> Heya,
>
> 
>
> > […]
>
> Overall, "null safe" can be very dangerous if made the default.
>
> Here's a scenario where I'd never want "null safe" behaviour (which does
> anything but introducing safety):
>
> ```php
> $accounts->get($receiver)
>     ->addFunds(
>         $accounts->get($sender)
>             ->detractFunds($amount)
>     );
> ```
>
> In the above scenario, if the first `$accounts->get()` call returns `null`
> for any reason, you may actually destroy money (funds detracted, but never
> added to another account).
>
> The example is simplistic, but it shows that "null safe" is everything but
> "safe", and it must instead be used only where it absolutely makes sense to
> suppress null reference errors.
>
> Similar behaviour can be observed around cast operators, which are too lax
> for most businesses logic:
> https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229
>
> Safe = crashes when it should crash.

---

## #112180 — Eugene Sidelnyk — 2020-11-04T18:39:01+00:00

URL: https://externals.io/message/112159#112180 · In reply to: #112179

Thus, can you provide any other dangerous example?



> But wait!
>
> In your example, funds won't get detracted. If `$accounts->get($receiver)`
> will return `null`, then everything inside `addFunds(...)` will not be
> executed.
> Your example (simplified): https://3v4l.org/38Dk3
>
> Another one:
> ```php
> function expensive_function() {
>     var_dump(__FUNCTION__);
> }
>
> $foo = null;
>
> $foo?->baz(expensive_function());
> ```
>
> 
>
> > […]

---

## #112182 — Christian Schneider — 2020-11-04T19:32:34+00:00

URL: https://externals.io/message/112159#112182 · In reply to: #112180

Am 04.11.2020 um 19:39 schrieb Eugene Sidelnyk <zsidelnik@gmail.com>:
> Thus, can you provide any other dangerous example?

I think at this point you could have realised that it is
a) a BC break (code which has thrown an exception before now wouldn't)
b) not finding any love among the community here. Possibly for a reason?

If you really want you could put an RFC together but I'm pretty sure that it wouldn't be accepted.

And now for your dangerous example:
	try {
		$foo = null;
		$foo->bar();
		deletel_all_files_on_machine();
	} catch (Error $dummy) {}


Regards,
- Chris

---

## #112183 — Eugene Sidelnyk — 2020-11-04T19:38:47+00:00

URL: https://externals.io/message/112159#112183 · In reply to: #112182

Yeah... Creating null was a huge mistake.
Now it is probably too late to fix that (maybe some new language can
introduce that).

But what do you think about introducing special class `NullObject`?

On Wed, Nov 4, 2020, 9:32 PM Christian Schneider <cschneid@cschneid.com>
wrote:

> Am 04.11.2020 um 19:39 schrieb Eugene Sidelnyk <zsidelnik@gmail.com>:
> > […]
>
> I think at this point you could have realised that it is
> a) a BC break (code which has thrown an exception before now wouldn't)
> b) not finding any love among the community here. Possibly for a reason?
>
> If you really want you could put an RFC together but I'm pretty sure that
> it wouldn't be accepted.
>
> And now for your dangerous example:
>         try {
>                 $foo = null;
>                 $foo->bar();
>                 deletel_all_files_on_machine();
>         } catch (Error $dummy) {}
>
>
> Regards,
> - Chris

---

## #112184 — Marco Pivetta — 2020-11-04T20:17:58+00:00

URL: https://externals.io/message/112159#112184 · In reply to: #112183

Hey,



> Yeah... Creating null was a huge mistake.
> Now it is probably too late to fix that (maybe some new language can
> introduce that).
>
>
Y'all confusing Java's `null` (billion dollar mistake) with PHP's `null`.

 * In Java, `null|object` passes the `object` property and parameter type
declaration, but crashes on `.` (`->` operator in PHP). That means that the
type system is fundamentally flawed.
 * In PHP, `null|object` does not pass the `object` property and parameter
type declaration, and crashes on `->`

The PHP `T|null` type is almost equivalent to `data Maybe T = Just T |
Nothing` from typed functional languages, and does not present the same
"billion dollar mistake" flaws of Java.
It is also an accurate and sufficient representation of "absence of value".

That's why I linked the `toString()` vs `(string)` example in
https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229

Also, this was previously discussed in a similar way in
https://externals.io/message/108369#108386

But what do you think about introducing special class `NullObject`?
>

You can really only apply the null object pattern (you can use the one from
https://github.com/Ocramius/ProxyManager/blob/2.9.1/docs/null-object.md,
which is relatively type-safe) when interactions with such an object
leading to no effect are valid.

In the example I wrote above:

Let's assume following repository signature:

```php
interface Accounts
{
    /** @throws AccountNotFoundException */
    public function get(AccountHolder $id): Account;
}
```

In following usage:

```php
$accounts->get($receiver)
    ->addFunds(
        $accounts->get($sender)
            ->detractFunds($amount)
    );
```

Assuming `->` were capable of operating with `object|null` (OP proposal),
if (by accident) somebody decided to change this signature:

```diff
interface Accounts
{
-    /** @throws AccountNotFoundException */
-    public function get(AccountHolder $id): Account;
+    public function get(AccountHolder $id): ?Account;
}
```

In this scenario, what can happen is that money disappears, as I've written
above:

 > In the above scenario, if the first `$accounts->get()` call returns
`null` for any reason, you may actually destroy money (funds detracted, but
never added to another account).

The same would happen if a `NullObject` were used:

```diff
interface Accounts
{
-    /** @throws AccountNotFoundException */
-    public function get(AccountHolder $id): Account;
+    public function get(AccountHolder $id): NullObject<Account>|Account;
}
```

Same scenario (slight variation):

 > In the above scenario, if the first `$accounts->get()` call returns `
NullObject<Account> ` for any reason, you may actually destroy money (funds
detracted, but never added to another account).

I would say that embracing nullability **in a type-safe manner** (please
use https://psalm.dev/ or https://phpstan.org/) leads to proper usage of
`null`, where it correctly indicates cases where no value has been
produced/found/calculated/etc.

Null pointer exceptions are trivially avoided by using any of these
relatively stable and well adopted static analysis tools, and we don't
really need to fight windmills at all.

---

## #112185 — Josh Bruce — 2020-11-04T20:18:11+00:00

URL: https://externals.io/message/112159#112185 · In reply to: #112183

> 
> 
> Yeah... Creating null was a huge mistake.
> Now it is probably too late to fix that (maybe some new language can
> introduce that).
> 
> But what do you think about introducing special class `NullObject`?

I would rather let an instance be “empty” than to have a unique, separate thing that always represents nothing. To be fair, I don’t know the specific NullObject implementation here - based on presumption - I would intentionally be creating something that represents nothing.

See also this RFC: https://wiki.php.net/rfc/objects-can-be-falsifiable <https://wiki.php.net/rfc/objects-can-be-falsifiable> - sounds like this thread might bring more supporters to that table/discussion.

Cheers,
Josh
