rfc:new_in_initializers
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:new_in_initializers [2021/03/03 10:56] – created nikic | rfc:new_in_initializers [2021/06/30 07:51] – nikic | ||
---|---|---|---|
Line 2: | Line 2: | ||
* Date: 2021-03-02 | * Date: 2021-03-02 | ||
* Author: Nikita Popov < | * Author: Nikita Popov < | ||
- | * Status: | + | * Status: |
* Proposed Version: PHP 8.1 | * Proposed Version: PHP 8.1 | ||
* Implementation: | * Implementation: | ||
Line 8: | Line 8: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | This RFC proposes to allow use of '' | + | This RFC proposes to allow use of '' |
Currently, code such as the following is not permitted: | Currently, code such as the following is not permitted: | ||
Line 36: | Line 36: | ||
This makes the actual default value less obvious (from an API contract perspective), | This makes the actual default value less obvious (from an API contract perspective), | ||
- | This RFC proposes to relax this restriction and allow the use of '' | + | This RFC proposes to relax this restriction and allow the use of '' |
===== Proposal ===== | ===== Proposal ===== | ||
- | '' | + | '' |
<PHP> | <PHP> | ||
Line 52: | Line 52: | ||
</ | </ | ||
- | The use of a dynamic or non-string class name is not allowed. The use of argument unpacking is not allowed. The use of unsupported expressions as arguments is not allowed. | + | The use of a dynamic or non-string class name or an anonymous class is not allowed. The use of argument unpacking is not allowed. The use of unsupported expressions as arguments is not allowed. |
<PHP> | <PHP> | ||
// All not allowed (compile-time error): | // All not allowed (compile-time error): | ||
function test( | function test( | ||
- | $foo = new (CLASS_NAME_CONSTANT)(), | + | $a = new (CLASS_NAME_CONSTANT)(), |
- | $bar = new A(...[]), // argument unpacking | + | $b = new class {}, // anonymous class |
- | $baz = new B($abc), // unsupported constant expression | + | $c = new A(...[]), // argument unpacking |
+ | $d = new B($abc), // unsupported constant expression | ||
) {} | ) {} | ||
</ | </ | ||
- | Affected positions | + | New expressions |
<PHP> | <PHP> | ||
Line 69: | Line 70: | ||
const C = new Foo; | const C = new Foo; | ||
+ | |||
+ | function test($param = new Foo) {} | ||
# | # | ||
class Test { | class Test { | ||
- | | + | |
- | public | + | public $prop = new Foo, |
- | | + | |
} | } | ||
- | |||
- | function test($param = new Foo) {} | ||
</ | </ | ||
- | ==== Evaluation of expressions | + | ==== Unsupported positions |
- | Static variable | + | New expressions continue to not be supported in (static and non-static) property |
- | Currently, all initializers in a class (and its parents) are evaluated | + | For non-static property initializers, the initializer expression needs to be evaluated on each object creation. There are currently two places where this could happen: As part of object |
- | For non-static property default values, parameter default values and attribute arguments, evaluation happens as-if the expression is evaluated on each object instantiation, each function call, or each attribute instantiation respectively. Any side-effects are observable | + | Performing |
- | If the construction | + | For static property initializers and class constant initializers a different evaluation order issue arises. Currently, these initializers are evaluated lazily the first time a class is used in a certain way (e.g. instantiated). Once initializers can contain potentially side-effecting expressions, |
+ | |||
+ | As such support in these contexts is delayed until such a time as a consensus on the preferred behavior can be reached. | ||
+ | |||
+ | ==== Order of evaluation ==== | ||
+ | |||
+ | Initializer expressions could always contain side-effects through autoloaders or error handlers. However, support for '' | ||
+ | |||
+ | * Static variable initializers are evaluated when control flow reaches the static variable declaration. | ||
+ | * Global constant initializers are evaluated when control flow reaches the constant declaration. | ||
+ | * Attribute arguments are evaluated from left to right on every call of '' | ||
+ | * Parameter default values are evaluated from left to right on every call to the function where the parameter is not explicitly passed. | ||
+ | |||
+ | Additionally, | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ==== Nested attributes ==== | ||
+ | |||
+ | It is worth mentioning explicitly that this RFC effectively adds support | ||
+ | |||
+ | < | ||
+ | # | ||
+ | </ | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | None. | + | This RFC does not introduce any backwards-incompatible changes, and also should not break any major assumptions. The only case where something genuinely new is possible are nested attributes. |
===== Future Scope ===== | ===== Future Scope ===== | ||
- | This RFC is narrow in that it only adds support for '' | + | This RFC omits support for '' |
+ | |||
+ | With the precedent set by '' | ||
===== Vote ===== | ===== Vote ===== | ||
- | Yes/No. | + | Voting opened on 2021-06-30 and closes on 2021-07-14. |
+ | |||
+ | <doodle title=" | ||
+ | | ||
+ | | ||
+ | </ | ||
rfc/new_in_initializers.txt · Last modified: 2021/07/14 07:19 by nikic