# [RFC] Nullable intersection types

- Thread: https://externals.io/message/115554
- Original archive: https://news-web.php.net/php.internals/115554
- Started by Nicolas Grekas on 2021-07-23T09:58:00+00:00
- Messages: 48
- RFC: Nullable intersection types (Declined) — https://externals.io/rfc/nullable_intersection_types.md
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/115554.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #115554 — Nicolas Grekas — 2021-07-23T09:58:00+00:00

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

Hi everyone,

as proposed by Nikita and Joe, I'm submitting this late RFC for your
consideration for inclusion in PHP 8.1. Intersection types as currently
accepted are not nullable. This RFC proposes to make them so.

I wrote everything down about the reasons why here:
https://wiki.php.net/rfc/nullable_intersection_types

Please have a look and let me know what you think.

Have a nice read,

Nicolas

---

## #115555 — Mark Randall — 2021-07-23T10:54:47+00:00

URL: https://externals.io/message/115554#115555 · In reply to: #115554

> Hi everyone,
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types


IMO we should require brackets and forbid not using them when combining 
unions and intersections.

These types are already going to be confusing enough and we can likely 
save a fair amount of confusion and pain down the line by requiring the 
explicit brackets.

Without wanting to bikeshed, let's just make sure we're set on () 
because whatever we choose here will be the defacto mechanism for 
declaring sub-types in PHP for the rest of eternity so it would need to 
be maximally compatible with everything we might want to do with them.

---

## #115556 — Guilliam Xavier — 2021-07-23T11:05:26+00:00

URL: https://externals.io/message/115554#115556 · In reply to: #115554

On Fri, Jul 23, 2021 at 11:58 AM Nicolas Grekas <nicolas.grekas@gmail.com>
wrote:

> Hi everyone,
>
> as proposed by Nikita and Joe, I'm submitting this late RFC for your
> consideration for inclusion in PHP 8.1. Intersection types as currently
> accepted are not nullable. This RFC proposes to make them so.
>
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types
>
> Please have a look and let me know what you think.
>
> Have a nice read,
>
> Nicolas
>

Hi Nicolas, thank you for putting this up.  Just two editorial notes:

- "This is because any intersection that contains the null type is
identical to the null type itself.": I don't think that `X&null` is the
same as `null` but rather like `never` (i.e. the "bottom/empty" type, or
simply "impossible/nonsensical/bogus")?

- "Should brackets around the intersection be: not needed / mandatory /
allow both styles": maybe clearer would be e.g. "forbidden / mandatory /
optional (allow both styles)"?

Regards,

-- 
Guilliam Xavier

---

## #115557 — Nicolas Grekas — 2021-07-23T12:11:43+00:00

URL: https://externals.io/message/115554#115557 · In reply to: #115556

Le ven. 23 juil. 2021 à 13:05, Guilliam Xavier <guilliam.xavier@gmail.com>
a écrit :

>
> On Fri, Jul 23, 2021 at 11:58 AM Nicolas Grekas <nicolas.grekas@gmail.com>
> wrote:
>
> > […]
>
> Hi Nicolas, thank you for putting this up.  Just two editorial notes:
>
> - "This is because any intersection that contains the null type is
> identical to the null type itself.": I don't think that `X&null` is the
> same as `null` but rather like `never` (i.e. the "bottom/empty" type, or
> simply "impossible/nonsensical/bogus")?
>
> - "Should brackets around the intersection be: not needed / mandatory /
> allow both styles": maybe clearer would be e.g. "forbidden / mandatory /
> optional (allow both styles)"?
>

Thanks, I edited both to the following:

- any intersections that contain the ''null'' type are identical to the
''never'' type.

- Intersections should be: without brackets around / with brackets around /
allow both styles

---

## #115558 — Benjamin Eberlei — 2021-07-23T12:13:57+00:00

URL: https://externals.io/message/115554#115558

> 
> > […]
>
>
> IMO we should require brackets and forbid not using them when combining
> unions and intersections.
>
> These types are already going to be confusing enough and we can likely
> save a fair amount of confusion and pain down the line by requiring the
> explicit brackets.
>
> Without wanting to bikeshed, let's just make sure we're set on ()
> because whatever we choose here will be the defacto mechanism for
> declaring sub-types in PHP for the rest of eternity so it would need to
> be maximally compatible with everything we might want to do with them.
>

This is also my preference to have it (A&B)|null - It is the least
"disruptive" change for this late stage of the release cycle and leaves the
most potential for future improvements.

>
> --
> 
> To unsubscribe, visit: https://www.php.net/unsub.php

---

## #115559 — Derick Rethans — 2021-07-23T12:36:50+00:00

URL: https://externals.io/message/115554#115559 · In reply to: #115554

> as proposed by Nikita and Joe, I'm submitting this late RFC for your 
> consideration for inclusion in PHP 8.1. Intersection types as 
> currently accepted are not nullable. This RFC proposes to make them 
> so.
> 
> I wrote everything down about the reasons why here: 
> https://wiki.php.net/rfc/nullable_intersection_types
> 
> Please have a look and let me know what you think.

From the RFC: «Taking all these elements into account, the preference 
of... and thus to use the "?X&Y" syntax».

I think this would be a mistake. You touch upon operator precedence, and 
needing to know whether | or & is higher, and inventing a new precedence 
for ?.

I would strongly advocate for not getting into the realm with any 
operator precendence, but instead *require* parenthesis for any 
combination. This gives the code reader and writer an immediate clue 
about what the code does. Most coding standards also recommend this for 
expressions in "if" statements and the like.

I do however agree with Sara's «over-delivering syntax that hasn't been 
entirely thought through» point. It will take a lot longer to come up 
with a proposal to combine intersection and union types.

That in combination that you're proposing this RFC after feature freeze, 
while you've had four months to make this arguments as part of the "Pure 
Intersection Types" RFC, I am currently not going to support this RFC 
for inclusion into PHP 8.1.

cheers,
Derick

-- 
PHP 7.4 Release Manager
Host of PHP Internals News: https://phpinternals.news
Like Xdebug? Consider supporting me: https://xdebug.org/support
https://derickrethans.nl | https://xdebug.org | https://dram.io
twitter: @derickr and @xdebug

---

## #115560 — Nicolas Grekas — 2021-07-23T13:10:36+00:00

URL: https://externals.io/message/115554#115560 · In reply to: #115559

> > […]
>
> From the RFC: «Taking all these elements into account, the preference
> of... and thus to use the "?X&Y" syntax».
>
> I think this would be a mistake. You touch upon operator precedence, and
> needing to know whether | or & is higher, and inventing a new precedence
> for ?.
>
> I would strongly advocate for not getting into the realm with any
> operator precendence, but instead *require* parenthesis for any
> combination. This gives the code reader and writer an immediate clue
> about what the code does. Most coding standards also recommend this for
> expressions in "if" statements and the like.
>
> I do however agree with Sara's «over-delivering syntax that hasn't been
> entirely thought through» point. It will take a lot longer to come up
> with a proposal to combine intersection and union types.
>

That's another reason why I prefer going with "?X&Y". The situation we have
here is very close to what we had back in 2016 when nullable types were
introduced: we figured out that nullability was very much needed now, so we
went with a syntax that would not overlap with a possible future RFC for
unions.

IMHO, going with (X&Y)|null is forcing a future we know little about.


> That in combination that you're proposing this RFC after feature freeze,
> while you've had four months to make this arguments as part of the "Pure
> Intersection Types" RFC, I am currently not going to support this RFC
> for inclusion into PHP 8.1.


I wish I could have spotted that this discussion was needed earlier.
Still, this is important for 8.1 (IMHO).

From the RFC:
> For userland, if this nullable capability were added to a later version
of PHP, making a parameter nullable later would cause a BC break (or force
a major version bump when using semver.)

Also this:
> When PHP 7.0 introduced scalar types, it was obvious that the special null
type was missing as a way to declare that null was a possible return value.
PHP 7.1 added the “?foo” syntax to declare their nullability. This lesson
from history tells us that the nullable type is special and very much
needed in PHP.

Nicolas

---

## #115561 — Levi Morrison via internals — 2021-07-23T14:16:40+00:00

URL: https://externals.io/message/115554#115561 · In reply to: #115559

>
> From the RFC: «Taking all these elements into account, the preference
> of... and thus to use the "?X&Y" syntax».
>
> I think this would be a mistake. You touch upon operator precedence, and
> needing to know whether | or & is higher, and inventing a new precedence
> for ?.
>
> I would strongly advocate for not getting into the realm with any
> operator precendence, but instead *require* parenthesis for any
> combination. This gives the code reader and writer an immediate clue
> about what the code does. Most coding standards also recommend this for
> expressions in "if" statements and the like.

I also strongly advocate for always requiring parentheses whenever
mixing unions and intersections, and I don't think the nullable
shorthand should be omitted from this rule.

---

## #115562 — Deleu — 2021-07-23T14:30:45+00:00

URL: https://externals.io/message/115554#115562 · In reply to: #115559

> From the RFC: «Taking all these elements into account, the preference
> of... and thus to use the "?X&Y" syntax».
>
> I think this would be a mistake. You touch upon operator precedence, and
> needing to know whether | or & is higher, and inventing a new precedence
> for ?.
>
> I would strongly advocate for not getting into the realm with any
> operator precendence, but instead *require* parenthesis for any
> combination. This gives the code reader and writer an immediate clue
> about what the code does. Most coding standards also recommend this for
> expressions in "if" statements and the like.
>
> I do however agree with Sara's «over-delivering syntax that hasn't been
> entirely thought through» point. It will take a lot longer to come up
> with a proposal to combine intersection and union types.
>
> That in combination that you're proposing this RFC after feature freeze,
> while you've had four months to make this arguments as part of the "Pure
> Intersection Types" RFC, I am currently not going to support this RFC
> for inclusion into PHP 8.1.
>
> cheers,
> Derick
>
> --
> PHP 7.4 Release Manager
> Host of PHP Internals News: https://phpinternals.news
> Like Xdebug? Consider supporting me: https://xdebug.org/support
> https://derickrethans.nl | https://xdebug.org | https://dram.io
> twitter: @derickr and @xdebug
>
> --
> 
> To unsubscribe, visit: https://www.php.net/unsub.php


These are precisely everything I think about this RFC. The only thing the
RFC made clear is why it is easy to make an exception for null while still
not providing a full mix of union and intersection.

Maybe my memory is also really bad, but the RFC makes it seem like version
7.0 was a mistake to be learned from which isn't clear for me. I understand
that introducing nullable intersection later will warrant a major version
and I don't see a problem with that. Pure Intersection RFC was such a
breeze vote precisely because it didn't involve the complexity of mixing
with union. Part of that complexity is now being rushed after feature
freeze.

-- 
Marco Aurélio Deleu

---

## #115563 — Benjamin Eberlei — 2021-07-23T14:48:40+00:00

URL: https://externals.io/message/115554#115563 · In reply to: #115562

> 
>
> > […]
>
>
> These are precisely everything I think about this RFC. The only thing the
> RFC made clear is why it is easy to make an exception for null while still
> not providing a full mix of union and intersection.
>
> Maybe my memory is also really bad, but the RFC makes it seem like version
> 7.0 was a mistake to be learned from which isn't clear for me. I understand
> that introducing nullable intersection later will warrant a major version
> and I don't see a problem with that. Pure Intersection RFC was such a
> breeze vote precisely because it didn't involve the complexity of mixing
> with union. Part of that complexity is now being rushed after feature
> freeze.
>

As a maintainer of a large open source library, yes 7.0 was a problem due
to the nullability missing for return types and was the reason why a lot of
open source libraries jumped from minimum 5.4/5.5/5.6 directly to 7.1 to
avoid breaking BC twice for classes/interfaces when a signature of the
following kind was present:

/**
* @param string $foo
 * @return ?string
 */
function foo () { }

php 7.0: foo(string $foo) {}
php 7.1: foo(string $foo) : ?string {}


> --
> Marco Aurélio Deleu

---

## #115564 — Theodore Brown — 2021-07-23T15:50:06+00:00

URL: https://externals.io/message/115554#115564 · In reply to: #115554

> Hi everyone,
>
> as proposed by Nikita and Joe, I'm submitting this late RFC for your
> consideration for inclusion in PHP 8.1. Intersection types as currently
> accepted are not nullable. This RFC proposes to make them so.
>
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types
>
> Please have a look and let me know what you think.


Hi Nicolas,

Thanks for your work on this. The RFC states:

> the preference of the author of this RFC is to define “?” as having
> a lower precedence than any other type-operator, and thus to use
> the “?X&Y” syntax.

I also strongly believe this would be a mistake. When union types
were introduced, it was explicitly decided not to use the `?(T1|T2)`
syntax, for the following reason [1]:

> this notation is both rather awkward syntactically, and differs from
> the well-established `T1|T2|null` syntax used by phpdoc comments. The
> discussion feedback was overwhelmingly in favor of supporting the
> `T1|T2|null` notation.

`?T` is a shorthand alias for `T|null`, and the alias cannot be used
to add `null` to a union type.

Although PHP doesn't yet support generalized union and intersection
type combinations, this is almost certainly something we'll want to
enable in the future (in fact, this very RFC is a step towards this).

But if union types don't support the shorthand nullability syntax,
and intersection types require it, how will the syntaxes be combined
in the future? E.g. will we write `null | A & B | C` or will it be
required to use something like `?A & B | C`?

The latter is not only syntactically awkward but also very confusing.

Since `|null` is the only supported syntax to add `null` to a union
type, for consistency the same syntax should be used to add `null` to
an intersection type. This will avoid confusion and inconsistency
down the road if a future RFC enables more general union and
intersection type combinations. It also avoids the need to define a
precedence for the `?` type operator.

As you note in the RFC, PHP already defines `|` as having a lower 
precedence than `&`, so `X & Y | null` can only be interpreted as
`(X & Y) | null`. This is consistent with other languages such as
TypeScript, where `A & B | C & D` is parsed as `(A & B) | (C & D)`.
[2]

Since precedence is already defined for this syntax consistently with
other languages, I don't think it's necessary to require parentheses
if we use the `A & B | null` syntax.

Best regards,  
Theodore


[1]: https://wiki.php.net/rfc/union_types_v2#nullable_union_types
[2]: https://github.com/Microsoft/TypeScript/pull/3622

---

## #115565 — Levi Morrison via internals — 2021-07-23T15:56:07+00:00

URL: https://externals.io/message/115554#115565 · In reply to: #115564

> As you note in the RFC, PHP already defines `|` as having a lower
> precedence than `&`, so `X & Y | null` can only be interpreted as
> `(X & Y) | null`. This is consistent with other languages such as
> TypeScript, where `A & B | C & D` is parsed as `(A & B) | (C & D)`.
> [2]
>
> Since precedence is already defined for this syntax consistently with
> other languages, I don't think it's necessary to require parentheses
> if we use the `A & B | null` syntax.

I want to acknowledge and reject this. Few people keep the bitwise
precedence information in their head. It's not worth it -- just
require parenthesis.

---

## #115566 — Pierre — 2021-07-23T16:06:34+00:00

URL: https://externals.io/message/115554#115566 · In reply to: #115565

Le 23/07/2021 à 17:56, Levi Morrison via internals a écrit :
> > […]
> I want to acknowledge and reject this. Few people keep the bitwise
> precedence information in their head. It's not worth it -- just
> require parenthesis.
>
I don't want to reject this, this is actually a very good point, do not 
reinvent a syntax that works somewhere else. And in the end, I do find 
this readable. (I prey that people will use space in they types 
definitions to make it even more readable, but style is not a topic for 
this RFC.)

Accumulating union and sum types is probably not something I'd do every 
day, so in the end, I'll probably always go and read the documentation 
each and every time. But for people that do, they'll get used to it fast 
enough I think.

This behavior seems fine, at least I think it's fine, as long as the 
documentation is clear.

Regards,

--

Pierre

---

## #115567 — Larry Garfield — 2021-07-23T16:25:40+00:00

URL: https://externals.io/message/115554#115567 · In reply to: #115566

> Le 23/07/2021 à 17:56, Levi Morrison via internals a écrit :
> > […]
> I don't want to reject this, this is actually a very good point, do not 
> reinvent a syntax that works somewhere else. And in the end, I do find 
> this readable. (I prey that people will use space in they types 
> definitions to make it even more readable, but style is not a topic for 
> this RFC.)
> 
> Accumulating union and sum types is probably not something I'd do every 
> day, so in the end, I'll probably always go and read the documentation 
> each and every time. But for people that do, they'll get used to it fast 
> enough I think.
> 
> This behavior seems fine, at least I think it's fine, as long as the 
> documentation is clear.

Requiring parenthesis now leaves the option open in the future to make them optional when doing full mixed types.

Making them optional now requires that they be optional in the future when doing full mixed types.

I vaguely recall there being some potential issue with making them optional for full mixed intersection/union types, but not the details.  Either way, it's a not-small decision to make, and may have complicated implications for future work.  It shouldn't be made on "eh, seems nicer" grounds in a post-freeze last minute RFC.

Making it required now is the safer option, as it allows more flexibility in the future once someone tries to implement full union/intersection mixing.  Making it optional later may still happen, I don't know, but it doesn't box us in to requiring it later.

--Larry Garfield

---

## #115568 — Pierre — 2021-07-23T16:28:12+00:00

URL: https://externals.io/message/115554#115568 · In reply to: #115567

Le 23/07/2021 à 18:25, Larry Garfield a écrit :
> Requiring parenthesis now leaves the option open in the future to make them optional when doing full mixed types.
>
> Making them optional now requires that they be optional in the future when doing full mixed types.
>
> I vaguely recall there being some potential issue with making them optional for full mixed intersection/union types, but not the details.  Either way, it's a not-small decision to make, and may have complicated implications for future work.  It shouldn't be made on "eh, seems nicer" grounds in a post-freeze last minute RFC.
>
> Making it required now is the safer option, as it allows more flexibility in the future once someone tries to implement full union/intersection mixing.  Making it optional later may still happen, I don't know, but it doesn't box us in to requiring it later.

This is a good point as well.

Regards,

--

Pierre

---

## #115570 — Mike Schinkel — 2021-07-24T03:53:35+00:00

URL: https://externals.io/message/115554#115570 · In reply to: #115554

> 
> 
> Hi everyone,
> 
> as proposed by Nikita and Joe, I'm submitting this late RFC for your
> consideration for inclusion in PHP 8.1. Intersection types as currently
> accepted are not nullable. This RFC proposes to make them so.
> 
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types
> 
> Please have a look and let me know what you think.
> 
> Have a nice read,
> 
> Nicolas

It seems this RFC is actually trying to accomplish two(2) things:

1. Add typehints for nullable intersection types to PHP.
2. Get PHP to support a preferred syntax for type-hinting nullable intersection types.

Further:

A. There seems to be consensus on the value of #1.
B. There seems to be consensus on using a syntax with parentheses for #1. 
C. There is a lot of pushback on #2.
D. The desired syntax in #2 would reduce future flexibility, as Larry Garfield commented. 

Given both of these sets of assertions I would ask the RFC's author and proponents what would be a worse outcome?

X. Getting typehints for nullable intersection types added to PHP, but not the desired syntax?
Y. Not getting typehints for nullable intersection types added to PHP? 

When answering please consider that #X is the outcome that would not preclude possibly getting #2 at a future date.

---------

Also, the entire discussion has claimed a "need" for nullable intersection types but AFAIIK they have been presented in completely abstract terms; i.e. no one has presented any real-world scenarios where they would actually use nullable intersection types.  

It might be helpful — or at least it would be for me — if the RFC could add two or three real-world example use-cases where the author and proponents would actually like to use nullable intersection types in their future PHP code.  

#jmtcw

-Mike

---

## #115571 — Tobias Nyholm — 2021-07-24T04:42:49+00:00

URL: https://externals.io/message/115554#115571 · In reply to: #115570

> It seems this RFC is actually trying to accomplish two(2) things:
> 
> 1. Add typehints for nullable intersection types to PHP.
> 2. Get PHP to support a preferred syntax for type-hinting nullable intersection types.

Yes of course. You cannot really do #1 without #2. 

I agree with Nicolas that `?X&Y` makes more sense. You add ? before the type. If the type is scalar, a class or an intersection type should not matter. But I hear some technical arguments from Derick so I won’t argue against that. 

Im fine with the syntax: `X & Y | null`
I don’t think parentheses should be required. From a mathematical perspective you want to add parentheses when you want to override the operation order. If you remove the parentheses and the expression has the same order of operations, then the parentheses is clearly not needed. 

@Larry makes an argument to keep them: 

> Requiring parenthesis now leaves the option open in the future to make them optional when doing full mixed types.


I don’t understand why we should require something that is not needed simply because it would give us an option to remove it later… Could you elaborate why this is important? (Im probably missing something)

> Given both of these sets of assertions I would ask the RFC's author and proponents what would be a worse outcome?

I don’t see how this question is relevant. We are not seeking compromises at the moment. We are seeking the best technical solution to a technical issue. 

> Also, the entire discussion has claimed a "need" for nullable intersection types but AFAIIK they have been presented in completely abstract terms; i.e. no one has presented any real-world scenarios where they would actually use nullable intersection types.  


The “need” is covered by the discussion about PHP 7.0. See this post as an example: https://externals.io/message/115554#115563 <https://externals.io/message/115554#115563>

——————

When reading my message above could make it sound like I am pessimistic. That is not true. I am excited about this change and I am happy PHP has a long feature freeze so issues like this can show up before the release. 

Regards,
Tobias


> 
> 
> > […]
> 
> It seems this RFC is actually trying to accomplish two(2) things:
> 
> 1. Add typehints for nullable intersection types to PHP.
> 2. Get PHP to support a preferred syntax for type-hinting nullable intersection types.
> 
> Further:
> 
> A. There seems to be consensus on the value of #1.
> B. There seems to be consensus on using a syntax with parentheses for #1. 
> C. There is a lot of pushback on #2.
> D. The desired syntax in #2 would reduce future flexibility, as Larry Garfield commented. 
> 
> Given both of these sets of assertions I would ask the RFC's author and proponents what would be a worse outcome?
> 
> X. Getting typehints for nullable intersection types added to PHP, but not the desired syntax?
> Y. Not getting typehints for nullable intersection types added to PHP? 
> 
> When answering please consider that #X is the outcome that would not preclude possibly getting #2 at a future date.
> 
> ---------
> 
> Also, the entire discussion has claimed a "need" for nullable intersection types but AFAIIK they have been presented in completely abstract terms; i.e. no one has presented any real-world scenarios where they would actually use nullable intersection types.  
> 
> It might be helpful — or at least it would be for me — if the RFC could add two or three real-world example use-cases where the author and proponents would actually like to use nullable intersection types in their future PHP code.  
> 
> #jmtcw
> 
> -Mike

---

## #115572 — Mike Schinkel — 2021-07-24T05:01:58+00:00

URL: https://externals.io/message/115554#115572 · In reply to: #115571

> 
> 
> > […]
> 
> Yes of course. You cannot really do #1 without #2. 
> 
> I agree with Nicolas that `?X&Y` makes more sense. You add ? before the type. If the type is scalar, a class or an intersection type should not matter. But I hear some technical arguments from Derick so I won’t argue against that. 
> 
> Im fine with the syntax: `X & Y | null`
> I don’t think parentheses should be required. From a mathematical perspective you want to add parentheses when you want to override the operation order. If you remove the parentheses and the expression has the same order of operations, then the parentheses is clearly not needed. 
> 
> @Larry makes an argument to keep them: 
> 
> > […]
> 
> 
> I don’t understand why we should require something that is not needed simply because it would give us an option to remove it later… Could you elaborate why this is important? (Im probably missing something)

The difference is if we make the decision to use the `?X&Y` syntax and we later realize it was a mistake then we are stuck with it. 

OTOH if we use the (X&Y)|null syntax and later realize it is okay to also allow `?X&Y` PHP could later be changed to allow it.

The later is the choice that manages future risk better.

> > […]
> 
> I don’t see how this question is relevant. We are not seeking compromises at the moment. We are seeking the best technical solution to a technical issue. 

If you are not willing to compromise you will probably get nothing.

It is relevant because I was trying to get you to ask yourself if you would be happier if you get half of what you want rather than none of what you want.  

Because there is a very real possibility you will get none of what you want if the RFC requires the syntax so many have objected to.

BTW, I do not have a strong opinion either way, but since I see than many do have a strong opinion I was trying to play arbitrator between two sets of people who each have very entrenched opinions where their opinions are in conflict.  If neither side will budge, nobody wins.  

> > […]
> 
> 
> The “need” is covered by the discussion about PHP 7.0. See this post as an example: https://externals.io/message/115554#115563 <https://externals.io/message/115554#115563>
That message mentioned the need in abstract, but it did not provide any real-world examples.  It claims that there were real-world examples, but did not show any.  

That message was also not part of the RFC.

Listen, I am trying to help make the RFC better to improve its chance of passing.  If you don't want that, then I will just demure.

-Mike

> 
> ——————
> 
> When reading my message above could make it sound like I am pessimistic. That is not true. I am excited about this change and I am happy PHP has a long feature freeze so issues like this can show up before the release. 
> 
> Regards,
> Tobias
> 
> 
> > […]

---

## #115573 — Tobias Nyholm — 2021-07-24T05:33:11+00:00

URL: https://externals.io/message/115554#115573 · In reply to: #115572

> > […]
> 
> The difference is if we make the decision to use the `?X&Y` syntax and we later realize it was a mistake then we are stuck with it. 
> 
> OTOH if we use the (X&Y)|null syntax and later realize it is okay to also allow `?X&Y` PHP could later be changed to allow it.
> 
> The later is the choice that manages future risk better.

I thought Larry was discussing `X & Y | null` vs `(X & Y) | null`. 
I’ve dropped `?X&Y` because Derick had technical arguments against it. 

The way I see it, there is no benefit in requiring the parentheses in `(X & Y) | null`. I suggest we use  `X & Y | null`.

> > […]
> 
> If you are not willing to compromise you will probably get nothing.
> 
> It is relevant because I was trying to get you to ask yourself if you would be happier if you get half of what you want rather than none of what you want.  
> 
> Because there is a very real possibility you will get none of what you want if the RFC requires the syntax so many have objected to.
> 
> BTW, I do not have a strong opinion either way, but since I see than many do have a strong opinion I was trying to play arbitrator between two sets of people who each have very entrenched opinions where their opinions are in conflict.  If neither side will budge, nobody wins.  


That is a strange attitude. You are saying that you rather see a release with a know flaw than actually trying to find the best solution. 
The release will be in 4 months. There is a process to clearly find issues like this. There is plenty of time to review this RFC and release it in beta 2 and let people test it. This is not a last minute thing, the process is designed for this. 

> > […]
> That message mentioned the need in abstract, but it did not provide any real-world examples.  It claims that there were real-world examples, but did not show any.  
> 
> That message was also not part of the RFC.

The first paragraph under “Rational” mentioned this: https://wiki.php.net/rfc/nullable_intersection_types#rationale <https://wiki.php.net/rfc/nullable_intersection_types#rationale>

In my world maintaining PHP libraries, it is obvious that 7.0 was missing this feature. As Benjamin mentioned, you could see that all libraries that migrated from 5.x just skipped 7.0 and went straight to support 7.1. I did the same for all my packages because of this reason. I made a misstake to assume that everybody had the same “world of maintaining PHP libraries” as I do. 

So the “real world examples” you are looking for is: 
If we don’t merge a version of this RFC in 8.1, PHP packages will not take leverage of the inspection types until PHP 8.2. The reason for a package to drop PHP 7 support is to be able to use the cool features in PHP 8. This will require a major release (something all maintainer should do sparsely). Why would I do a new major release if I cannot properly define my API (interfaces)? I rather wait to next PHP version where I can express my API and do my major release then. 

As the RFC states and Benjamin made extra clear, this is exactly what happened with PHP 7.0. 

> 
> Listen, I am trying to help make the RFC better to improve its chance of passing.  If you don't want that, then I will just demure.

> 

Sorry if I sounded (or keep sounding negative). I appriciate you and everybody else participate in this discussion. We are all trying to make PHP better and we are all trying to move this RFC forward. 

// Tobias

---

## #115574 — Jordan LeDoux — 2021-07-24T06:43:29+00:00

URL: https://externals.io/message/115554#115574 · In reply to: #115571

I do not think this is strictly true. The issue that this RFC is running
into is that combination types between intersections and unions was
something that was avoided for the intersection types RFC. Not because the
authors never thought of it, but because the RFC would have become very
broad and encompassed many different discussions. But since the issue of
adding combination types *only* for null is now being presented, it seems
to me that a lot of people are taking the position that the syntax for it
should match what the future implementation of combination types is to
avoid confusion. I don't think that's an unreasonable position to take, and
the difficulty of that discussion perhaps illustrates why this wasn't
included in the original RFC.

> We are not seeking compromises at the moment. We are seeking the best
technical solution to a technical issue.

But this presumes that the ONLY technical issue at hand is the ability to
have nullable intersections. Intersections are only available for class
types, you can't use intersections with scalars. The *best* technical
solution since there are no scalars is for people to use classes which have
a null state internally, or at least I could argue that's the case. (In
fact I *did* argue that's the case in a previous thread.)

I'm not even convinced that this is a technical issue at this point, so the
idea that there's no need for compromise is rather strange to me.

If the goal is to support nothing but nullable intersections, there's an
entire programming pattern[1] to solve that concern. But as nulls have
always just "worked" for most PHP developers, I *can* see the argument for
it despite the fact that I think it promotes bad program design. I know
that I will use intersection types with the null object pattern in my own
libraries even if nullable intersection types are added.

So given that it's a special case of combination types, it makes sense that
people are at least *discussing* what combination types should look like
longer term.

> I don’t understand why we should require something that is not needed
simply because it would give us an option to remove it later…

The point (I think) that Larry was making is that the parentheses can
always be made optional in the future, but if this is delivered without
parentheses now, it will be very, very hard to make parenthesis mandatory
later (BC break) if there is a reason to do so. What would that reason be?
I'm not sure, because a full implementation and RFC for combination types
hasn't been proposed yet

So requiring parentheses places the fewest restrictions on the anticipated
future RFC for combination types and allows the author to find the best
technical solution to *that* issue.

---

[1]: https://en.wikipedia.org/wiki/Null_object_pattern

On Fri, Jul 23, 2021 at 9:43 PM Tobias Nyholm <tobias.nyholm@gmail.com>
wrote:

> > […]
> intersection types.
>
> Yes of course. You cannot really do #1 without #2.
>
> I agree with Nicolas that `?X&Y` makes more sense. You add ? before the
> type. If the type is scalar, a class or an intersection type should not
> matter. But I hear some technical arguments from Derick so I won’t argue
> against that.
>
> Im fine with the syntax: `X & Y | null`
> I don’t think parentheses should be required. From a mathematical
> perspective you want to add parentheses when you want to override the
> operation order. If you remove the parentheses and the expression has the
> same order of operations, then the parentheses is clearly not needed.
>
> @Larry makes an argument to keep them:
>
> > […]
> them optional when doing full mixed types.
>
>
> I don’t understand why we should require something that is not needed
> simply because it would give us an option to remove it later… Could you
> elaborate why this is important? (Im probably missing something)
>
> > […]
> proponents what would be a worse outcome?
>
> I don’t see how this question is relevant. We are not seeking compromises
> at the moment. We are seeking the best technical solution to a technical
> issue.
>
> > […]
> intersection types but AFAIIK they have been presented in completely
> abstract terms; i.e. no one has presented any real-world scenarios where
> they would actually use nullable intersection types.
>
>
> The “need” is covered by the discussion about PHP 7.0. See this post as an
> example: https://externals.io/message/115554#115563 <
> https://externals.io/message/115554#115563>
>
> ——————
>
> When reading my message above could make it sound like I am pessimistic.
> That is not true. I am excited about this change and I am happy PHP has a
> long feature freeze so issues like this can show up before the release.
>
> Regards,
> Tobias
>
>
> > […]
> wrote:
> > […]
> intersection types.
> > […]
> #1.
> > […]
> Garfield commented.
> > […]
> proponents what would be a worse outcome?
> > […]
> not the desired syntax?
> > […]
> preclude possibly getting #2 at a future date.
> > […]
> intersection types but AFAIIK they have been presented in completely
> abstract terms; i.e. no one has presented any real-world scenarios where
> they would actually use nullable intersection types.
> > […]
> add two or three real-world example use-cases where the author and
> proponents would actually like to use nullable intersection types in their
> future PHP code.
> > […]

---

## #115575 — Deleu — 2021-07-24T08:17:56+00:00

URL: https://externals.io/message/115554#115575 · In reply to: #115573

>
> > […]
> and proponents what would be a worse outcome?
> > […]
> compromises at the moment. We are seeking the best technical solution to a
> technical issue.
>

The very essence of this whole RFC is rooted in compromise. This is a new
feature being discussed after feature freeze. If best technical solution is
what we should seek, then this discussion should target 8.2.


>
>
> That is a strange attitude. You are saying that you rather see a release
> with a know flaw than actually trying to find the best solution.
> The release will be in 4 months. There is a process to clearly find issues
> like this. There is plenty of time to review this RFC and release it in
> beta 2 and let people test it. This is not a last minute thing, the process
> is designed for this.


Where does it say that feature freeze exists so that more features can be
built after the freeze?



>
> So the “real world examples” you are looking for is:
> If we don’t merge a version of this RFC in 8.1, PHP packages will not take
> leverage of the inspection types until PHP 8.2.
>
> As the RFC states and Benjamin made extra clear, this is exactly what
> happened with PHP 7.0.
>

And that's OK! Pure Intersection was voted that way 30 against 3 the way
that it was! You can steer clear from intersection in libraries on 8.1 and
use it on application code only, provide feedback and be part of a
healthier discussion when extending its capabilities to cover what
libraries need at a later stage.

---

## #115576 — Mike Schinkel — 2021-07-24T13:11:58+00:00

URL: https://externals.io/message/115554#115576 · In reply to: #115573

> 
> > […]
> 
> 
> That is a strange attitude. You are saying that you rather see a release with a know flaw than actually trying to find the best solution. 
> The release will be in 4 months. There is a process to clearly find issues like this. There is plenty of time to review this RFC and release it in beta 2 and let people test it. This is not a last minute thing, the process is designed for this. 

That is begging the question. It is not a "known flaw" — it is a perfectly fine option — it is just not your preference.  Arguing the syntax is squarely in the realm of bike-shedding.

> > […]
> 
> The first paragraph under “Rational” mentioned this: https://wiki.php.net/rfc/nullable_intersection_types#rationale <https://wiki.php.net/rfc/nullable_intersection_types#rationale>
I see no code examples showing real-world use-cases in the "Rational" section, I just see an abstract assertion by the author explain why they believe it is needed.

I don't get the pushback on providing real-world use-case examples. Clearly with your work in Symfony — given the assumption that nullable intersection types are really needed — you must has at least a few examples.  Why not provide them?

> In my world maintaining PHP libraries, it is obvious that 7.0 was missing this feature. As Benjamin mentioned, you could see that all libraries that migrated from 5.x just skipped 7.0 and went straight to support 7.1. I did the same for all my packages because of this reason. I made a misstake to assume that everybody had the same “world of maintaining PHP libraries” as I do. 

My understanding from all interactions on this list is that posters saying that something is important is (almost?) never sufficient. Instead it is incumbent upon RFC authors and RFC supporters to go the extra mile and make a strong case for why something is needed.  And thus far, I have not seen any actual cases where it is needed, I have only heard assertions.

Note I am not against this. I tend to prefer more functionality in a language, not less.  So by asking you to give examples I am actually trying to help you make your case. And it is puzzling to me why you are pushing back so hard when I ask for use-cases.

> So the “real world examples” you are looking for is: 
> If we don’t merge a version of this RFC in 8.1, PHP packages will not take leverage of the inspection types until PHP 8.2. The reason for a package to drop PHP 7 support is to be able to use the cool features in PHP 8. This will require a major release (something all maintainer should do sparsely). Why would I do a new major release if I cannot properly define my API (interfaces)? I rather wait to next PHP version where I can express my API and do my major release then. 

That is not a real-world example of why nullable intersection types are really needed. That is an assertion about library maintainer's concerns who want nullable intersection types. 

It is not code nor does it have anything mention of how any use-cases where nullable intersection types would be applied.

> Sorry if I sounded (or keep sounding negative). I appriciate you and everybody else participate in this discussion. We are all trying to make PHP better and we are all trying to move this RFC forward. 

Then give some actual examples instead of just repeating assertions that this is needed and if you don't get it you believe it will make your life more difficult as a library maintainer. 

There are tens of things that make my life difficult every day I program in PHP, but this list doesn't care about my own or any of our difficulties, it cares about real-world use-cases that would provide reason why a feature needs to be added to PHP.

-Mike

P.S. Also, what Deleu said.

---

## #115577 — Joe Watkins — 2021-07-24T15:34:21+00:00

URL: https://externals.io/message/115554#115577 · In reply to: #115576

This is not a new feature. This is a detail of a feature that was not well
understood for whatever reason.

That is why we are willing to fix it after freeze.

I would ask anyone voting to vote on the basis of the detail and leave
timing to be the problem of release managers. Voting negatively because you
don't agree that we should fix it at this time might be considered harmful
(to the feature, which we already accepted).

Cheers
Joe



> > […]
> wrote:
> > […]
> would be happier if you get half of what you want rather than none of what
> you want.
> > […]
> want if the RFC requires the syntax so many have objected to.
> > […]
> many do have a strong opinion I was trying to play arbitrator between two
> sets of people who each have very entrenched opinions where their opinions
> are in conflict.  If neither side will budge, nobody wins.
> > […]
> with a know flaw than actually trying to find the best solution.
> > […]
> issues like this. There is plenty of time to review this RFC and release it
> in beta 2 and let people test it. This is not a last minute thing, the
> process is designed for this.
>
> That is begging the question. It is not a "known flaw" — it is a perfectly
> fine option — it is just not your preference.  Arguing the syntax is
> squarely in the realm of bike-shedding.
>
> > […]
> real-world examples.  It claims that there were real-world examples, but
> did not show any.
> > […]
> https://wiki.php.net/rfc/nullable_intersection_types#rationale <
> https://wiki.php.net/rfc/nullable_intersection_types#rationale>
> I see no code examples showing real-world use-cases in the "Rational"
> section, I just see an abstract assertion by the author explain why they
> believe it is needed.
>
> I don't get the pushback on providing real-world use-case examples.
> Clearly with your work in Symfony — given the assumption that nullable
> intersection types are really needed — you must has at least a few
> examples.  Why not provide them?
>
> > […]
> missing this feature. As Benjamin mentioned, you could see that all
> libraries that migrated from 5.x just skipped 7.0 and went straight to
> support 7.1. I did the same for all my packages because of this reason. I
> made a misstake to assume that everybody had the same “world of maintaining
> PHP libraries” as I do.
>
> My understanding from all interactions on this list is that posters saying
> that something is important is (almost?) never sufficient. Instead it is
> incumbent upon RFC authors and RFC supporters to go the extra mile and make
> a strong case for why something is needed.  And thus far, I have not seen
> any actual cases where it is needed, I have only heard assertions.
>
> Note I am not against this. I tend to prefer more functionality in a
> language, not less.  So by asking you to give examples I am actually trying
> to help you make your case. And it is puzzling to me why you are pushing
> back so hard when I ask for use-cases.
>
> > […]
> take leverage of the inspection types until PHP 8.2. The reason for a
> package to drop PHP 7 support is to be able to use the cool features in PHP
> 8. This will require a major release (something all maintainer should do
> sparsely). Why would I do a new major release if I cannot properly define
> my API (interfaces)? I rather wait to next PHP version where I can express
> my API and do my major release then.
>
> That is not a real-world example of why nullable intersection types are
> really needed. That is an assertion about library maintainer's concerns who
> want nullable intersection types.
>
> It is not code nor does it have anything mention of how any use-cases
> where nullable intersection types would be applied.
>
> > […]
> everybody else participate in this discussion. We are all trying to make
> PHP better and we are all trying to move this RFC forward.
>
> Then give some actual examples instead of just repeating assertions that
> this is needed and if you don't get it you believe it will make your life
> more difficult as a library maintainer.
>
> There are tens of things that make my life difficult every day I program
> in PHP, but this list doesn't care about my own or any of our difficulties,
> it cares about real-world use-cases that would provide reason why a feature
> needs to be added to PHP.
>
> -Mike
>
> P.S. Also, what Deleu said.

---

## #115578 — Levi Morrison via internals — 2021-07-24T19:47:01+00:00

URL: https://externals.io/message/115554#115578 · In reply to: #115573

> That is a strange attitude. You are saying that you rather see a release with a [known] flaw than actually trying to find the best solution.

Sorry, but sometimes features take time either due to technical
reasons (variance was difficult to get right this way), or due to
disagreements in voters. Just as we added scalar and return types in
7.0 but nullable types came only in 7.1, I think it's fine to add pure
intersection types in 8.1 and add the ability to mix unions and
intersections in 8.2.

Is it _ideal_? No, but I'd rather wait than rush something in. There
has been a lot of disagreement in this proposal, and I personally
don't feel comfortable including this in any form for 8.1 because of
this. I would rather wait, and waiting has the advantage that we can
get a cohesive proposal for it to work with all unions and
intersections, and not just a special case.

---

## #115579 — drealecs@gmail.com — 2021-07-24T21:03:57+00:00

URL: https://externals.io/message/115554#115579 · In reply to: #115554

> Hi everyone,
>
> as proposed by Nikita and Joe, I'm submitting this late RFC for your
> consideration for inclusion in PHP 8.1. Intersection types as currently
> accepted are not nullable. This RFC proposes to make them so.
>
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types
>
> Please have a look and let me know what you think.
>

Given the discussion, I think it might be better to remove all other syntax
alternatives other than (X&Y)|null. There are persons here that mentioned
they wish to wait for 8.2 than agree with 2/3 on the feature where the
syntax might not be the most forward compatible one.

One alternative could be to agree on a voting scheme where there could be 3
options:
- No.
- Yes, but only with (X&Y)|null.
- Yes, any syntax, with additional vote on preferred syntax
aiming for 2/3 on the second or third option.

Regards,
Alex

---

Next page: https://externals.io/message/115554.md?page=2
