rfc:nullsafe_operator

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:nullsafe_operator [2020/07/14 08:36] – Adjust voting date range ilutovrfc: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: Under discussion+  * Status: Implemented
   * Target Version: PHP 8.0   * Target Version: PHP 8.0
   * Implementation: https://github.com/php/php-src/pull/5619   * Implementation: https://github.com/php/php-src/pull/5619
Line 10: Line 10:
 ===== Introduction ===== ===== Introduction =====
  
-This RFC proposes new operator nullsafe operator ''%%?->%%'' with full short circuiting.+This RFC proposes the new nullsafe operator ''%%?->%%'' with full short circuiting.
  
 ===== Proposal ===== ===== Proposal =====
Line 76: Line 76:
   * Nullsafe method call (''%%?->%%'')   * Nullsafe method call (''%%?->%%'')
   * Static method call (''%%::%%'')   * Static method call (''%%::%%'')
-  * Assignment (''%%=%%'', ''%%+=%%'', ''%%??=%%'', ''%%= &%%'', etc.) 
-  * 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 ''%%[]%%'' of an array access   * The expression in ''%%[]%%'' of an array access
Line 103: Line 100:
 //       --------  chain 2 //       --------  chain 2
 // If $c is null chain 2 is aborted, method d() isn't called, null is passed to `$a->b()` // If $c is null chain 2 is aborted, method d() isn't called, null is passed to `$a->b()`
- 
-   $foo?->bar = $a->b(); 
-// -------------------- chain 1 
-//              ------- chain 2 
-// If $foo is null chain 1 is aborted, `$a->b()` is not evaluated, the assignment is skipped 
- 
-   $foo?->bar++; 
-// ------------ chain 1 
-// If $foo is null, chain 1 is aborted, ++ is skipped 
 </code> </code>
 ==== Rationale ==== ==== Rationale ====
Line 121: Line 109:
 $foo?->bar(expensive_function()); $foo?->bar(expensive_function());
 </code> </code>
-The evaluation of ''%%expensive_function()%%'' is undesirable if ''%%$foo%%'' is ''%%null%%'' as its result will simply be discarded. If the function has side effects it could also lead to surpsises.+The evaluation of ''%%expensive_function()%%'' is undesirable if ''%%$foo%%'' is ''%%null%%'' as its result will simply be discarded. If the function has side effects it could also lead to surprises.
  
 **2. You can see which methods/properties return null** **2. You can see which methods/properties return null**
Line 131: Line 119:
 Without short circuiting every subsequent method call and property access in the chain will require using the nullsafe operator or you will get a “Call to a member function on null” error. With short circuiting this isn’t necessary which makes it more obvious which methods/properties might return ''%%null%%''. Without short circuiting every subsequent method call and property access in the chain will require using the nullsafe operator or you will get a “Call to a member function on null” error. With short circuiting this isn’t necessary which makes it more obvious which methods/properties might return ''%%null%%''.
  
-**3. Allows for nullsafe operator in write context** +**3. Mixing with other operators**
- +
-<code php> +
-$foo = null; +
-$foo?->bar = 'bar'; +
-var_dump($foo); +
- +
-// Without short circuiting: +
-// Fatal error: Can't use nullsafe result value in write context +
- +
-// With short circuiting: +
-// NULL +
-</code> +
-Without short circuiting the assignment to a nullsafe property would be illegal because it produces an r-value (a value that cannot be assigned to). With short circuiting if a nullsafe operation on the left hand side of the assignment fails the assignment is simply skipped. +
- +
-**4. Mixing with other operators**+
  
 <code php> <code php>
Line 189: Line 162:
 ===== Syntax choice ===== ===== Syntax choice =====
  
-The ''%%?%%'' in ''%%?->%%'' denotes the precise place in the code where the short circuiting occurs. It closesly resembles the syntax of every other language that implements a nullsafe operator.+The ''%%?%%'' in ''%%?->%%'' denotes the precise place in the code where the short circuiting occurs. It closely resembles the syntax of every other language that implements a nullsafe operator
 + 
 +===== Forbidden usages ===== 
 + 
 +==== Nullsafe operator in write context ==== 
 + 
 +Using the nullsafe operator in write context ist not allowed. 
 + 
 +<code php> 
 +$foo?->bar->baz = 'baz'; 
 +// Can't use nullsafe operator in write context 
 + 
 +foreach ([1, 2, 3] as $foo?->bar->baz) {} 
 +// Can't use nullsafe operator in write context 
 + 
 +unset($foo?->bar->baz); 
 +// Can't use nullsafe operator in write context 
 + 
 +[$foo?->bar->baz] = 'baz'; 
 +// Assignments can only happen to writable values 
 +</code> 
 +It was previously suggested to allow the nullsafe operator in the left hand side of assignments and skip the assignment if the left hand side of the nullsafe operator was ''%%null%%''. However, due to technical difficulties this is not a part of this RFC. It might be addressed in a later RFC. It is also not completely clear whether the right hand side of the assignment should always be evaluated or not.
  
-===== References =====+==== 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 can sometimes return the r-value ''%%null%%''. 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 can sometimes return the r-value ''%%null%%''.
Line 238: Line 232:
 ===== Vote ===== ===== Vote =====
  
-Voting starts 2020-07-15 and ends 2020-07-29+Voting starts 2020-07-17 and ends 2020-07-31
  
 <doodle title="Add nullsafe operator to the language?" auth="ilutov" voteType="single" closed="true"> <doodle title="Add nullsafe operator to the language?" auth="ilutov" voteType="single" closed="true">
rfc/nullsafe_operator.1594715775.txt.gz · Last modified: 2020/07/14 08:36 by ilutov