rfc:new_without_parentheses
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:new_without_parentheses [2023/12/29 15:08] – Improved the Ambiguity section vudaltsov | rfc:new_without_parentheses [2024/05/28 18:04] (current) – Added Target Version vudaltsov | ||
---|---|---|---|
Line 2: | Line 2: | ||
* Date: 2023-12-29 | * Date: 2023-12-29 | ||
- | * Author: Valentin Udaltsov | + | * Author: Valentin Udaltsov |
- | * Status: | + | * Status: |
+ | * Target Version: PHP 8.4 | ||
+ | * Discussion: https:// | ||
* First Published at: http:// | * First Published at: http:// | ||
* Implementation: | * Implementation: | ||
Line 9: | Line 11: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | The "Class member access on instantiation" | + | The "class member access on instantiation" |
[[https:// | [[https:// | ||
- | Since then methods, properties and constants | + | Since then constants, properties and methods |
- | but **only** if the new expression is wrapped in parentheses: | + | variable, but **only** if the '' |
<code php> | <code php> | ||
- | class MyClass | + | class Request implements Psr\Http\Message\RequestInterface |
{ | { | ||
- | | + | |
- | { | + | |
- | echo ' | + | |
- | } | + | |
} | } | ||
- | (new MyClass())->method(); // Hello, World! | + | // OK |
+ | $request = (new Request())->withMethod(' | ||
- | new MyClass()-> | + | // PHP Parse error: syntax error, unexpected token " |
+ | $request = new Request()-> | ||
</ | </ | ||
- | The goal of this RFC is to enable the second | + | The goal of this RFC is to enable the second |
- | * make coding with PHP more convenient, | + | * make coding with PHP more convenient |
- | * lower the learning curve, | + | * decrease the visual debt in all sorts of builders and configurators ([[https:// |
- | * decrease the visual debt, | + | * ease switching between |
- | * ease transition from other C-like languages that don't require parentheses ([[https:// | + | |
- | ===== Ambiguity? | + | ===== Proposal |
- | At first glance '' | + | This RFC allows |
- | '' | + | |
- | does not exist: '' | + | |
- | constructor arguments, not as instantiation of '' | + | |
- | Here's how it is solved | + | <code php> |
- | '' | + | class MyClass extends ArrayObject |
- | Thus PHP offers 3 ways to provide a class: | + | { |
+ | const CONSTANT = ' | ||
+ | public static $staticProperty = ' | ||
+ | public static function staticMethod(): | ||
+ | public $property = ' | ||
+ | public function method(): string { return ' | ||
+ | public function __invoke(): string { return ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | one will be able to write | ||
+ | |||
+ | <code php> | ||
+ | var_dump( | ||
+ | new MyClass():: | ||
+ | new MyClass():: | ||
+ | new MyClass():: | ||
+ | new MyClass()-> | ||
+ | new MyClass()-> | ||
+ | new MyClass()(), | ||
+ | new MyClass([' | ||
+ | ); | ||
+ | |||
+ | $myClass = MyClass:: | ||
+ | var_dump( | ||
+ | new $myClass():: | ||
+ | new $myClass():: | ||
+ | new $myClass():: | ||
+ | new $myClass()-> | ||
+ | new $myClass()-> | ||
+ | new $myClass()(), | ||
+ | new $myClass([' | ||
+ | ); | ||
+ | |||
+ | var_dump( | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | new (trim(' | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | This RFC does not change behavior of '' | ||
+ | |||
+ | <code php> | ||
+ | new MyClass:: | ||
+ | new $myClass:: | ||
+ | new MyClass:: | ||
+ | new $myClass:: | ||
+ | new $myObject-> | ||
+ | new MyArrayConst[' | ||
+ | new $myArray[' | ||
+ | </ | ||
+ | |||
+ | This RFC allows to omit parentheses around the '' | ||
+ | parentheses are present or not: | ||
+ | |||
+ | <code php> | ||
+ | var_dump( | ||
+ | // string(8) " | ||
+ | new class { const CONSTANT = ' | ||
+ | // string(14) " | ||
+ | new class { public static $staticProperty = ' | ||
+ | // string(12) " | ||
+ | new class { public static function staticMethod() { return ' | ||
+ | // string(8) " | ||
+ | new class { public $property = ' | ||
+ | // string(6) " | ||
+ | new class { public function method() { return ' | ||
+ | // string(8) " | ||
+ | new class { public function __invoke() { return ' | ||
+ | // string(5) " | ||
+ | new class ([' | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | ===== Why the proposed syntax is unambiguous ===== | ||
+ | |||
+ | At first glance '' | ||
+ | is it '' | ||
+ | of class '' | ||
+ | is because PHP interprets the first expression after '' | ||
+ | |||
+ | Consider also '' | ||
+ | It is interpreted as '' | ||
+ | The same is true for '' | ||
+ | |||
+ | Here's how it looks at the [[https:// | ||
+ | The formula for the '' | ||
+ | where '' | ||
<code php> | <code php> | ||
- | // class_name | ||
new MyClass(); | new MyClass(); | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—class_name | ||
+ | |||
- | // new_variable | ||
new $class(); | new $class(); | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—new_variable (cannot have calls!) | ||
- | // (expr) | ||
new (trim(' | new (trim(' | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—(expr) | ||
</ | </ | ||
- | This guarantees that the '' | + | Once the parser encounters '' |
- | whatever comes next a class name. Hence it's safe and unambiguous to further use the '' | + | This guarantees that the '' |
- | own without parentheses. It's like replacing | + | without |
+ | are crucial for the proposed syntax: parentheses denote the end of the class name and the end of the new expression. | ||
- | ===== Proposal | + | ===== Other syntax ideas ===== |
- | TODO | + | Some of the ideas expressed during the discussion of this RFC are listed below. They are orthogonal to this proposal and |
+ | require a separate RFC. | ||
+ | |||
+ | ==== Allow to omit the new keyword ==== | ||
+ | |||
+ | Some languages like Kotlin allow to instantiate classes via [[https:// | ||
+ | Omitting the " | ||
+ | (in Kotlin [[https:// | ||
+ | deprecate declaring functions and classes with the same names. | ||
+ | |||
+ | ==== MyClass:: | ||
+ | |||
+ | Introducing a dedicated static constructor like '' | ||
+ | break for already existing static or object methods named '' | ||
+ | type different from '' | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | None. | + | None. Any code that is valid before the change will be valid after and interpreted in the same way. |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
PHP 8.4 | PHP 8.4 | ||
+ | |||
+ | ===== Proposed Voting Choices ===== | ||
+ | |||
+ | This is a simple yes-or-no vote to include this feature. 2/3 majority required to pass. | ||
+ | |||
+ | Voting started on 2024-05-09 and will end on 2024-05-24 00:00 GMT. | ||
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
+ | |||
+ | ===== Implementation ===== | ||
+ | |||
+ | Pull request contains the final implementation and plenty of tests asserting the expected behavior and backward compatibility: | ||
+ | |||
+ | ===== References ===== | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | Old requests for this feature: | ||
+ | |||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
rfc/new_without_parentheses.1703862519.txt.gz · Last modified: 2023/12/29 15:08 by vudaltsov