On Friday, July 23, 2021 at 4:58 AM Nicolas Grekas <nicolas.gre...@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.


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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to