rfc:nullsafe_operator
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:nullsafe_operator [2020/06/06 12:55] – Add benefits/drawbacks of short circuiting ilijatovilo | rfc:nullsafe_operator [2020/07/31 08:55] (current) – Close vote ilutov | ||
---|---|---|---|
Line 3: | Line 3: | ||
* Date: 2020-06-02 | * Date: 2020-06-02 | ||
* Author: Ilija Tovilo, tovilo.ilija@gmail.com | * Author: Ilija Tovilo, tovilo.ilija@gmail.com | ||
- | * Status: | + | * Status: |
* Target Version: PHP 8.0 | * Target Version: PHP 8.0 | ||
* Implementation: | * Implementation: | ||
Line 10: | Line 10: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | This RFC proposes | + | This RFC proposes |
===== Proposal ===== | ===== Proposal ===== | ||
Line 19: | Line 19: | ||
<code php> | <code php> | ||
- | |||
$country = null; | $country = null; | ||
Line 45: | Line 44: | ||
When the left hand side of the operator evaluates to '' | When the left hand side of the operator evaluates to '' | ||
- | ==== Short circuiting ==== | + | ===== Short circuiting |
- | This RFC proposes | + | ==== Introduction ==== |
+ | |||
+ | Short circuiting refers to skipping the evaluation of an expression based on some given condition. Two common examples are the operators '' | ||
+ | |||
+ | <code php> | ||
+ | null? | ||
+ | </ | ||
+ | **1. Short circuiting for neither method arguments nor chained method calls** | ||
+ | |||
+ | This complete lack of short circuiting is currently only found in Hack. Both the function '' | ||
+ | |||
+ | **2. Short circuiting for method arguments but not chained method calls** | ||
+ | |||
+ | This is what would normally be considered lack of short circuiting. The function '' | ||
+ | |||
+ | **3. Short circuiting for both method arguments and chained method calls** | ||
+ | |||
+ | We’ll refer to this as full short circuiting. | ||
+ | |||
+ | ==== Proposal ==== | ||
+ | |||
+ | This RFC proposes full short circuiting. When the evaluation of one element in the chain fails the execution of the entire chain is aborted and the entire chain evaluates to '' | ||
* Array access ('' | * Array access ('' | ||
Line 56: | Line 76: | ||
* Nullsafe method call ('' | * Nullsafe method call ('' | ||
* Static method call ('' | * Static method call ('' | ||
- | * Assignment ('' | ||
- | * Post/pre increment ('' | ||
The following elements will cause new sub-chains. | The following elements will cause new sub-chains. | ||
- | * Right hand side of an assignment | ||
* Arguments in a function call | * Arguments in a function call | ||
* The expression in '' | * The expression in '' | ||
+ | * The expression in '' | ||
Chains are automatically inferred. Only the closest chain will terminate. The following examples will try to illustrate. | Chains are automatically inferred. Only the closest chain will terminate. The following examples will try to illustrate. | ||
Line 82: | Line 100: | ||
// | // | ||
// If $c is null chain 2 is aborted, method d() isn't called, null is passed to `$a-> | // If $c is null chain 2 is aborted, method d() isn't called, null is passed to `$a-> | ||
+ | </ | ||
+ | ==== Rationale ==== | ||
- | | + | **1. It avoids surprises** |
- | // -------------------- chain 1 | + | |
- | // ------- chain 2 | + | |
- | // If $foo is null chain 1 is aborted, `$a-> | + | |
- | $foo? | + | <code php> |
- | // ------------ chain 1 | + | $foo = null; |
- | // If $foo is null, chain 1 is aborted, ++ is skipped | + | $foo? |
</ | </ | ||
- | ===== Syntax choice ===== | + | The evaluation of '' |
- | The syntax has been chosen to indicate the precise place in the code that the short circuiting | + | **2. You can see which methods/ |
+ | |||
+ | <code php> | ||
+ | $foo = null; | ||
+ | $foo? | ||
+ | </ | ||
+ | Without short circuiting every subsequent method call and property access | ||
+ | |||
+ | **3. Mixing with other operators** | ||
+ | |||
+ | <code php> | ||
+ | $foo = null; | ||
+ | $baz = $foo? | ||
+ | var_dump($baz); | ||
+ | |||
+ | // Without short circuiting: | ||
+ | // Notice: Trying to access array offset on value of type null | ||
+ | // NULL | ||
+ | |||
+ | // With short circuiting | ||
+ | // NULL | ||
+ | </ | ||
+ | Since with short circuiting the array access '' | ||
===== Other languages ===== | ===== Other languages ===== | ||
Line 117: | Line 156: | ||
* In Object-C accessing properties and calling methods on '' | * In Object-C accessing properties and calling methods on '' | ||
† Possible via [[https:// | † Possible via [[https:// | ||
- | ‡ Hack evaluates method arguments even if the callee | + | ‡ Hack evaluates method arguments even if the left hand side of '' |
8/13 languages have a nullsafe operator. 4/8 of those implement the nullsafe operator with short circuiting. | 8/13 languages have a nullsafe operator. 4/8 of those implement the nullsafe operator with short circuiting. | ||
- | ===== Why short circuiting? | + | ===== Syntax choice |
- | As with most things | + | The '' |
- | ==== Benefits | + | ===== Forbidden usages ===== |
- | **1. You can see which methods/ | + | ==== Nullsafe operator in write context ==== |
+ | |||
+ | Using the nullsafe operator in write context ist not allowed. | ||
<code php> | <code php> | ||
- | // Without short circuiting | + | $foo? |
- | $foo? | + | // Can't use nullsafe operator in write context |
- | // With short circuiting | + | foreach ([1, 2, 3] as $foo? |
- | $foo? | + | // Can't use nullsafe operator in write context |
+ | |||
+ | unset($foo? | ||
+ | // Can't use nullsafe operator in write context | ||
+ | |||
+ | [$foo? | ||
+ | // Assignments can only happen to writable values | ||
</ | </ | ||
- | In this example '' | + | It was previously suggested to allow the nullsafe operator |
- | **2. Allows for nullsafe operator | + | ==== References ==== |
+ | |||
+ | Taking the reference of a nullsafe chain is not allowed. This is because references require l-values (memory locations, like variables or properties) but the nullsafe operator | ||
<code php> | <code php> | ||
- | $foo? | + | $x = &$foo? |
- | var_dump($foo); | + | |
- | // Without short circuiting: | + | // Could loosely be translated to |
- | // Fatal error: Can't use nullsafe result value in write context | + | |
- | // With short circuiting: | + | if ($foo !== null) { |
- | // NULL | + | $x = & |
+ | } else { | ||
+ | $x = & | ||
+ | | ||
+ | } | ||
</ | </ | ||
- | Without short circuiting | + | For this reason, |
- | + | ||
- | **3. Mixing with other operators** | + | |
<code php> | <code php> | ||
- | $baz = $foo? | + | // 1 |
- | var_dump($baz); | + | $x = &$foo? |
+ | // Compiler error: Cannot take reference of a nullsafe chain | ||
- | // Without short circuiting: | + | // 2 |
- | // Notice: Trying to access array offset on value of type null | + | takes_ref($foo? |
- | // NULL | + | // Error: Cannot pass parameter 1 by reference |
- | // With short circuiting | + | // 3 |
- | // NULL | + | function & |
+ | return $foo? | ||
+ | | ||
+ | } | ||
</ | </ | ||
- | Since with short circuiting the array access '' | + | Example 2 is a runtime error because |
- | + | ||
- | ==== Drawbacks ==== | + | |
- | + | ||
- | **1. More rules** | + | |
- | + | ||
- | Short circuiting must define which elements belong to the short circuiting chain and which do not. Not all of them might be immediately obvious but they should be intuitive for the most part. | + | |
- | + | ||
- | **2. Complexity** | + | |
- | + | ||
- | It’s also very likely that the implementation of the nullsafe operator will be slightly more complicated than the alternative. No short circutiing poses it’s own set of complications though (like checking that '' | + | |
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
Line 185: | Line 228: | ||
Since PHP 7.4 a notice is emitted on array access on '' | Since PHP 7.4 a notice is emitted on array access on '' | ||
- | The same also goes for a nullsafe function call syntax ('' | + | A nullsafe function call syntax ('' |
===== Vote ===== | ===== Vote ===== | ||
- | … | + | Voting starts 2020-07-17 and ends 2020-07-31. |
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ |
rfc/nullsafe_operator.1591448117.txt.gz · Last modified: 2020/06/06 12:55 by ilijatovilo