rfc:nullable_intersection_types

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:nullable_intersection_types [2021/07/23 12:09]
nicolasgrekas
rfc:nullable_intersection_types [2021/08/29 19:13]
marandall Updated status tag after being declined (announced on ML).
Line 3: Line 3:
   * Date: 2021-07-22   * Date: 2021-07-22
   * Author: Nicolas Grekas, nicolasgrekas@php.net   * Author: Nicolas Grekas, nicolasgrekas@php.net
-  * Status: Under Discussion+  * Status: Declined
   * Implementation: https://github.com/php/php-src/pull/7259   * Implementation: https://github.com/php/php-src/pull/7259
   * First Published at: https://wiki.php.net/rfc/nullable_intersection_types   * First Published at: https://wiki.php.net/rfc/nullable_intersection_types
Line 28: Line 28:
 } }
 </PHP> </PHP>
 +
 +On the reflection side, ''ReflectionIntersectionType::allowsNull()'' will return ''true''/''false'' depending on what the intersection type accepts.
  
 ===== Rationale ===== ===== Rationale =====
Line 39: Line 41:
  
 For all these reasons, this RFC proposes to make intersection types nullable, and to make them so right away in PHP 8.1. For all these reasons, this RFC proposes to make intersection types nullable, and to make them so right away in PHP 8.1.
 +
 +About reflection, one could imagine a more complex model based on a ''ReflectionIntersectionType'' nested inside a ''ReflectionUnionType''. This RFC proposes to rely on ''ReflectionIntersectionType::allowsNull()'' instead. This is consistent with how ''T|null'' is returned without ''ReflectionUnionType'' wrapper, and is also simpler for userland to deal with.
  
 ===== Future Scope ===== ===== Future Scope =====
Line 64: Line 68:
 Since both possibilities contain several operators ("''?''" and "''&''" / "''|''" and "''&''" respectively), operator precedence should be taken into account to resolve any possible ambiguity when interpreting the type expression. PHP already defines "''|''" as having a lower precedence than the "''&''" operators. This means that "''X&Y|null''" can only be interpreted as "''(X&Y) | null''", which is what we want to express here. Since both possibilities contain several operators ("''?''" and "''&''" / "''|''" and "''&''" respectively), operator precedence should be taken into account to resolve any possible ambiguity when interpreting the type expression. PHP already defines "''|''" as having a lower precedence than the "''&''" operators. This means that "''X&Y|null''" can only be interpreted as "''(X&Y) | null''", which is what we want to express here.
  
-The precedence of the "''?''" type-operator is not defined yet. Looking at the precedence of null-related operators (see [[https://php.net/language.operators.precedence|this table]]), they are all below the "''&''" and "''|''" operators, which is what we need to unambiguously interpret "''?X&Y''" as "''? (X&Y)''". Another consideration related to composite types backs this interpretation up: whatever the nesting level of an hypothetical composite type definition, nullability can always we expressed as a single flag that sits next to the non-null constraints of the type. This is because any intersection that contains the ''null'' type is identical to the ''never'' type.+The precedence of the "''?''" type-operator is not defined yet. Looking at the precedence of null-related operators (see [[https://php.net/language.operators.precedence|this table]]), they are all below the "''&''" and "''|''" operators, which is what we need to unambiguously interpret "''?X&Y''" as "''? (X&Y)''". Another consideration related to composite types backs this interpretation up: whatever the nesting level of an hypothetical composite type definition, nullability can always we expressed as a single flag that sits next to the non-null constraints of the type. This is because any intersections that contain the ''null'' type are identical to the ''never'' type.
  
 Taking all these elements into account, 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. This reads quickly from left to right as: 1. the type is nullable 2. here are the constraints that apply to any non-null values. Taking all these elements into account, 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. This reads quickly from left to right as: 1. the type is nullable 2. here are the constraints that apply to any non-null values.
Line 84: Line 88:
 </PHP> </PHP>
  
-That being said and because it's kinda hard to gather a broad consensus on syntax choices, this RFC proposes various possible options for the community to decide. Using ''null|X&Y'' is not offered as an option because it would be "over-delivering syntax that hasn't been entirely thought through" (using sgolemon's words) and that should be introduced by a potential future RFC that would extend to composite types.+That being said and because it's kinda hard to gather a broad consensus on syntax choices, this RFC proposes various possible options for the community to decide. Using "''null|X&Y''is not offered as an option because it would be "over-delivering syntax that hasn't been entirely thought through" (using sgolemon's words) and that should be introduced by a potential future RFC that would extend to composite types.
  
 It is also the author's opinion that introducing brackets would be over-delivering syntax. Precedence rules + "nullability is a flag" arguments make them unnecessary. Not using brackets also eases with visual reading, to quickly spot eg the end of the signature of a function declaration. This is still offered as a possible vote option. It is also the author's opinion that introducing brackets would be over-delivering syntax. Precedence rules + "nullability is a flag" arguments make them unnecessary. Not using brackets also eases with visual reading, to quickly spot eg the end of the signature of a function declaration. This is still offered as a possible vote option.
Line 97: Line 101:
   * Preferred syntax: "?" prefix / "|null" suffix   * Preferred syntax: "?" prefix / "|null" suffix
   * Intersections should be: without brackets around / with brackets around / allow both styles   * Intersections should be: without brackets around / with brackets around / allow both styles
 +
 +===== Vote =====
 +
 +Voting starts 2021-08-13 09:30 UTC and ends 2021-08-27 17:00 UTC.
 +
 +<doodle title="Make intersection types nullable" auth="nicolasgrekas" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +
 +----
 +
 +<doodle title="Preferred syntax" auth="nicolasgrekas" voteType="single" closed="true">
 +   * "?" prefix
 +   * "|null" suffix
 +</doodle>
 +
 +----
 +
 +<doodle title="Intersections should be" auth="nicolasgrekas" voteType="single" closed="true">
 +   * without brackets around
 +   * with brackets around
 +   * allow both styles
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
rfc/nullable_intersection_types.txt · Last modified: 2021/08/29 19:13 by marandall