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 22:31] – Added Proposal 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 15: | Line 17: | ||
<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? ===== | + | |
- | + | ||
- | At first glance '' | + | |
- | '' | + | |
- | does not exist: '' | + | |
- | constructor arguments, not as instantiation of '' | + | |
- | + | ||
- | Here's how it is solved at the [[https:// | + | |
- | The formula for the '' | + | |
- | is a variable expression without calls. Thus PHP offers 3 ways to provide a class: | + | |
- | + | ||
- | <code php> | + | |
- | // class_name | + | |
- | new MyClass(); | + | |
- | + | ||
- | // new_variable | + | |
- | new $class(); | + | |
- | + | ||
- | // (expr) | + | |
- | new (trim(' | + | |
- | </ | + | |
- | + | ||
- | This guarantees that the '' | + | |
- | whatever comes next a class name. Hence it's safe and unambiguous to further use the '' | + | |
- | own without parentheses. It's like refactoring '' | + | |
- | nobody will ever read it as '' | + | |
===== Proposal ===== | ===== Proposal ===== | ||
- | This RFC allows to omit parentheses around '' | + | This RFC allows to omit parentheses around |
<code php> | <code php> | ||
- | class MyClass | + | class MyClass |
{ | { | ||
const CONSTANT = ' | const CONSTANT = ' | ||
Line 76: | Line 49: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | one will be able to write | ||
<code php> | <code php> | ||
Line 85: | Line 60: | ||
new MyClass()-> | new MyClass()-> | ||
new MyClass()(), | new MyClass()(), | ||
+ | new MyClass([' | ||
); | ); | ||
Line 95: | Line 71: | ||
new $myClass()-> | new $myClass()-> | ||
new $myClass()(), | new $myClass()(), | ||
+ | new $myClass([' | ||
); | ); | ||
Line 104: | Line 81: | ||
new (trim(' | new (trim(' | ||
new (trim(' | new (trim(' | ||
+ | new (trim(' | ||
); | ); | ||
</ | </ | ||
- | This RFC preserves grammar for '' | + | This RFC does not change behavior of '' |
- | omitting parentheses around the '' | + | |
<code php> | <code php> | ||
- | (new MyClass)::$staticProperty; // Access static property on MyClass instance | + | new MyClass::CONSTANT; // will continue to throw a syntax error |
- | new MyClass:: | + | new $myClass:: |
- | + | new MyClass:: | |
- | (new $myClass):: | + | new $myClass:: |
- | new $myClass:: | + | new $myObject-> |
- | + | new MyArrayConst[' | |
- | (new $myClass)-> | + | new $myArray[' |
- | new $myClass-> | + | |
- | + | ||
- | (new $myClass)-> | + | |
- | new $myClass-> | + | |
</ | </ | ||
- | This RFC allows to omit parentheses around | + | This RFC allows to omit parentheses around |
- | parentheses: | + | parentheses |
<code php> | <code php> | ||
Line 141: | Line 114: | ||
// string(8) " | // string(8) " | ||
new class { public function __invoke() { return ' | 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> | ||
+ | new MyClass(); | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—class_name | ||
+ | |||
+ | |||
+ | new $class(); | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—new_variable (cannot have calls!) | ||
+ | |||
+ | new (trim(' | ||
+ | ^ | ||
+ | | | ||
+ | |—T_NEW | ||
+ | | | ||
+ | |—(expr) | ||
+ | </ | ||
+ | |||
+ | Once the parser encounters '' | ||
+ | This guarantees that the '' | ||
+ | without any additional parentheses. It also becomes clear why '' | ||
+ | are crucial for the proposed syntax: parentheses denote the end of the class name and the end of the new expression. | ||
+ | |||
+ | ===== Other syntax ideas ===== | ||
+ | |||
+ | 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 ===== | ||
Line 151: | Line 188: | ||
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.1703889108.txt.gz · Last modified: 2023/12/29 22:31 by vudaltsov