# [RFC][VOTE] Nullable Types

- Thread: https://externals.io/message/93149
- Original archive: https://news-web.php.net/php.internals/93149
- Started by Levi Morrison on 2016-05-10T15:22:47+00:00
- Messages: 16
- 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

---

## #93149 — Levi Morrison — 2016-05-10T15:22:47+00:00

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

Dmitry and I have opened [voting on Nullable Types][1]. Note that I
have changed the phrasing of the two votes but the structure and
outcomes are the same. Hopefully these changes help clarify the
possible results.

I thank everyone who has contributed to the implementation or
discussion for their participation.

  [1]: https://wiki.php.net/rfc/nullable_types#voting_choices

---

## #93152 — Levi Morrison — 2016-05-10T16:27:53+00:00

URL: https://externals.io/message/93149#93152 · In reply to: #93149

> Dmitry and I have opened [voting on Nullable Types][1]. Note that I
> have changed the phrasing of the two votes but the structure and
> outcomes are the same. Hopefully these changes help clarify the
> possible results.
>
> I thank everyone who has contributed to the implementation or
> discussion for their participation.
>
>   [1]: https://wiki.php.net/rfc/nullable_types#voting_choices

Voting will close on Friday, May 20th, 2016 sometime in the evening of UTC-6.

---

## #93164 — Lester Caine — 2016-05-10T19:13:31+00:00

URL: https://externals.io/message/93149#93164 · In reply to: #93152

> Voting will close on Friday, May 20th, 2016 sometime in the evening of UTC-6.

Quick question ... if I simply strip this extra '?' if some library has
added it will it actually make any difference to the results?
I still think the whole concept of 'null' needs much better
documentation in relation to how it fits in generally.

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93168 — Levi Morrison — 2016-05-10T20:26:33+00:00

URL: https://externals.io/message/93149#93168 · In reply to: #93164

> 
> > […]
>
> Quick question ... if I simply strip this extra '?' if some library has
> added it will it actually make any difference to the results?
> I still think the whole concept of 'null' needs much better
> documentation in relation to how it fits in generally.
>
> --
> Lester Caine - G8HFL
> -----------------------------
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
>
> --
> 
> 

It can affect the results.

    function foo(?Foo $param) {}

If any code out there is calling foo with null then that code will now
break if you remove the question mark.

---

## #93224 — Lester Caine — 2016-05-11T10:26:52+00:00

URL: https://externals.io/message/93149#93224 · In reply to: #93168

> It can affect the results.
> 
>     function foo(?Foo $param) {}
> 
> If any code out there is calling foo with null then that code will now
> break if you remove the question mark.

Cart before Horse comes to mind ...

If the function is going to fail if you pass in a null ... you check for
the null before calling it. OK the '?' is a flag that you need to do
that, but you really need proper documentation as to just what Foo
expects. If I've handled the null case situation, the ? is redundant?

I'm still failing to see an overall picture of what people are trying to
achieve. Adding errors means that those errors need to be handled. If
the function gets a 'null' then there is a reason, and either the
function should not have been called ... workflow failed ... or the
function should simply handle the 'null' case. If the '?' throws an
error the workflow is broken after the event where a user code warning
would be more helpful.

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93225 — Quim Calpe — 2016-05-11T10:40:10+00:00

URL: https://externals.io/message/93149#93225 · In reply to: #93224

> 
> > […]
>
> Cart before Horse comes to mind ...
>
> If the function is going to fail if you pass in a null ... you check for
> the null before calling it. OK the '?' is a flag that you need to do
> that, but you really need proper documentation as to just what Foo
> expects. If I've handled the null case situation, the ? is redundant?
>

function foo(?Foo $param) Is not going to fail if you pass a null,
precisely "?" allow you to pass a null


I'm still failing to see an overall picture of what people are trying to
> achieve. Adding errors means that those errors need to be handled. If
> the function gets a 'null' then there is a reason, and either the
> function should not have been called ... workflow failed ... or the
> function should simply handle the 'null' case. If the '?' throws an
> error the workflow is broken after the event where a user code warning
> would be more helpful.
>
> --
> Lester Caine - G8HFL
> -----------------------------
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93226 — Michael Wallner — 2016-05-11T10:42:05+00:00

URL: https://externals.io/message/93149#93226 · In reply to: #93224

> 
> > […]
> 
> Cart before Horse comes to mind ...
> 
> If the function is going to fail if you pass in a null ... you check for

Why do you assume it'll fail?

> the null before calling it. OK the '?' is a flag that you need to do
> that, but you really need proper documentation as to just what Foo
> expects. If I've handled the null case situation, the ? is redundant?
> 
> I'm still failing to see an overall picture of what people are trying to
> achieve. Adding errors means that those errors need to be handled. If
> the function gets a 'null' then there is a reason, and either the
> function should not have been called ... workflow failed ... or the
> function should simply handle the 'null' case. If the '?' throws an
> error the workflow is broken after the event where a user code warning
> would be more helpful.
> 

	function foo(?Foo $param)

is equivalent to

	function foo(Foo $param = null)

except the former does not provide a default, i.e. it requires an
argument being passed to a call to foo().

-- 
Regards,
Mike

---

## #93263 — Davey Shafik — 2016-05-12T10:21:04+00:00

URL: https://externals.io/message/93149#93263 · In reply to: #93224

By removing the ?, the function doesn't fail because it can no longer
handle a null, the _engine_ throws an error because you're no longer
allowed to _pass_ a null, it doesn't even execute the function itself.

If you were to either a) define it as ?Foo $foo = null in the first place,
or b) change ?Foo $foo to Foo $foo = null, it would execute without error.

However, the semantics of calling it has changed, in the case of ?Foo $foo,
you're allowing the caller to _explicitly_ call it and pass in a null, but
not to call it without specifying anything. If you add the default of null
(= null), you are now allowing them to call it without anything, and
_implicitly_ passing in a null. This could lead to very subtle bugs.

E.g. the behavior of passing executing with a null value for the argument
is something you should be consciously making a decision on, and passing in
null explicitly.

- Davey



> 
> > […]
>
> Cart before Horse comes to mind ...
>
> If the function is going to fail if you pass in a null ... you check for
> the null before calling it. OK the '?' is a flag that you need to do
> that, but you really need proper documentation as to just what Foo
> expects. If I've handled the null case situation, the ? is redundant?
>
> I'm still failing to see an overall picture of what people are trying to
> achieve. Adding errors means that those errors need to be handled. If
> the function gets a 'null' then there is a reason, and either the
> function should not have been called ... workflow failed ... or the
> function should simply handle the 'null' case. If the '?' throws an
> error the workflow is broken after the event where a user code warning
> would be more helpful.
>
> --
> Lester Caine - G8HFL
> -----------------------------
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93267 — Lester Caine — 2016-05-12T11:36:30+00:00

URL: https://externals.io/message/93149#93267 · In reply to: #93263

> E.g. the behavior of passing executing with a null value for the
> argument is something you should be consciously making a decision on,
> and passing in null explicitly.

I was actually getting the logic wrong... the problem with this proposal
is that I HAVE to add the '?' for many of my libraries to continue to
work simply because they do handle the null case. So what was a working
system is broken by this change.

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93268 — Michael Wallner — 2016-05-12T11:39:56+00:00

URL: https://externals.io/message/93149#93268 · In reply to: #93267

> 
> > […]
> 
> I was actually getting the logic wrong... the problem with this proposal
> is that I HAVE to add the '?' for many of my libraries to continue to
> work simply because they do handle the null case. So what was a working
> system is broken by this change.
> 

So you already have function foo(Foo $foo = null)?
No need to change anything.

-- 
Regards,
Mike

---

## #93270 — Lester Caine — 2016-05-12T11:50:19+00:00

URL: https://externals.io/message/93149#93270 · In reply to: #93268

> 
> > […]
> So you already have function foo(Foo $foo = null)?
> No need to change anything.

To be honest I don't know ... *I* would not necessarily add '= null'
because that is the default case anyway ... I'm not sure fromthis
'little change' just what the full knock on effect is to code that goes
back 15 years?

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93273 — Rowan Collins — 2016-05-12T12:38:47+00:00

URL: https://externals.io/message/93149#93273 · In reply to: #93267

> 
> > […]
>
> I was actually getting the logic wrong... the problem with this proposal
> is that I HAVE to add the '?' for many of my libraries to continue to
> work simply because they do handle the null case. So what was a working
> system is broken by this change.
>

As I understand it, no existing code will change behaviour under this 
proposal. It merely adds an extra feature which libraries *can* use. 
What's more, it's a feature which makes those libraries *less strict*, 
not more.

Existing code:

function something(Bar $bar) {}
something(new Bar); // OK
something(); // Error: Missing required parameter
something(null); // Error: Parameter is not of required type

function something_else(Bar $bar = null) {}
something_else(new Bar); // OK
something_else(); // OK
something_else(null); // OK

None of this behaviour is going to change, no existing code will break.


Now let's say the author of the something function decides to use the 
new nullable type hint:

function something(?Bar $bar) {}
something(new Bar); // OK
something(); // Error: Missing required parameter
something(null); // OK

None of your code will be calling something(null) yet, because it was 
previously an error. So you now have an *extra* way of calling the 
function, but you don't need to change any existing usages.


The only breaking change would be if the author of the something_else 
function decided to make the argument mandatory but nullable, so that 
"something_else()" would be an error, but "something_else(null)" 
wouldn't be. But that's just the same as if they made the argument 
completely mandatory - it's a breaking change in the library, not 
something the language change has caused to happen.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #93276 — Lester Caine — 2016-05-12T13:46:10+00:00

URL: https://externals.io/message/93149#93276 · In reply to: #93273

> Now let's say the author of the something function decides to use the
> new nullable type hint:
> 
> function something(?Bar $bar) {}
> something(new Bar); // OK
> something(); // Error: Missing required parameter
> something(null); // OK
> 
> None of your code will be calling something(null) yet, because it was
> previously an error. So you now have an *extra* way of calling the
> function, but you don't need to change any existing usages.

I'm sorry to be dragging this out, but some of this stuff IS getting
more and more difficult to untangle!

The key element *I* of cause am miss reading is the (Bar ...) which is a
type hint. That will not exist in any of the code prior to ? and that is
the key to what is being discussed. No type hint ... no change?

If someone 'improves' a third party library by adding type hints then
this is were the using code needs to be checked?

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #93277 — Rowan Collins — 2016-05-12T14:26:27+00:00

URL: https://externals.io/message/93149#93277 · In reply to: #93276

> The key element *I* of cause am miss reading is the (Bar ...) which is a
> type hint. That will not exist in any of the code prior to ? and that is
> the key to what is being discussed. No type hint ... no change?
>
> If someone 'improves' a third party library by adding type hints then
> this is were the using code needs to be checked?

Correct. It should be no different from what can be done with existing 
type hints - if I change a library you were using from "function 
foo($bar)" to "function foo(Bar $bar)", it's possible you were passing a 
different object in and will now get an error.

If my library was always expecting Bar objects anyway, I'm arguably 
doing you a favour by forcing you to fix a long-standing bug where you 
passed the wrong thing.


The way I like to think about type hints in PHP is sugar for assertions 
at the top of the function:

function foo(Bar $bar) {
#...
}

is roughly equivalent to:

funtion foo($bar) {
assert($bar instanceOf Bar);
#...
}


The new syntax is just a different sugar, so that:

function foo(?Bar $bar) {
#...
}

is roughly equivalent to:

funtion foo($bar) {
assert(is_null($bar) || $bar instanceOf Bar);
#...
}


If the language didn't support typehints at all, I could add assertions 
like that in my library, and cause basically the same behaviour if you 
call my functions the wrong way.

[Strictly, in PHP 7, it's more like "if ( ! CHECK ) { throw new 
TypeError; }" rather than `assert()`, but the default result is the same.]

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #93292 — Mathieu Rochette — 2016-05-12T19:47:44+00:00

URL: https://externals.io/message/93149#93292 · In reply to: #93270

> 
> > […]
> To be honest I don't know ... *I* would not necessarily add '= null'
> because that is the default case anyway ... I'm not sure fromthis
> 'little change' just what the full knock on effect is to code that goes
> back 15 years?
you don't need to add '= null' or '?' anywhere. function that already
accepts
null arguments (either because it's untyped or because there is '=
null') will
continue to accept without any changes

adding '?' will make the function more permissive. not adding it will
not make
any existing function more restrictive
>

-- 
Mathieu Rochette

---

## #93409 — Pascal MARTIN — 2016-05-20T07:29:07+00:00

URL: https://externals.io/message/93149#93409 · In reply to: #93149

Le 10/05/2016 à 17:22, Levi Morrison a écrit :
> Dmitry and I have opened [voting on Nullable Types][1].
>    [1]: https://wiki.php.net/rfc/nullable_types#voting_choices
Hi,

At AFUP, we would be +1 for having nullable types, for both parameters 
and return values.

It often seems, with PHP 7.0, this specific feature is missing ;-)
A few indicated "int?" would have seemed more familiar than "?int", but 
it doesn't seem like a deal-breaker; and being close to Hack is more 
important than being close to - say - C#.
In our discussions, more (not a big margin though) were +1 for nullable 
types on parameters than on return values; no deal-breaker here either.

Anyway, happy to see votes are going well and nullables types are more 
than likely coming for PHP 7.1!

Thanks for you work on this!

-- 
Pascal MARTIN, AFUP - French UG
http://php-internals.afup.org/
