Dear all,
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassign
As a quick intro, my motivation for that RFC is that I find it quite
annoying that readonly properties play badly with CPP (constructor property
promotion).
Doing simple processing of any argument before assigning it to a readonly
property forces opting out of CPP.
This RFC would allow setting once a readonly property in the body of a
constructor after the property was previously (and implicitly) set using
CPP.
This allows keeping property declarations in their compact form while still
enabling validation, normalization, or conditional initialization.
Cheers,
Nicolas
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassign
I read in the linked PR:
"Team work with Claude Code opus 4.5 💪"
This makes me instantly want to vote no to this.
Code LLMs have been trained on all kinds of open source (and perhaps
proprietary?) software. Open Source nearly always atleast has an
"Attribution Required" license. But, these "tools" do not follow these
licenses and the required.
Therefore, there is no legally possible way to allow AI/LLM
contributions into the PHP source code.
cheers,
Derick
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignI read in the linked PR:
"Team work with Claude Code opus 4.5 💪"This makes me instantly want to vote no to this.
I assume it was not your intention, but the stated message here then
is: if you use an LLM to contribute to PHP, keep that information private /
do not disclose that information, otherwise you run the risk of getting
your contribution rejected due to personal subjective opinion beyond the
merits of your contribution.
Code LLMs have been trained on all kinds of open source (and perhaps
proprietary?) software. Open Source nearly always atleast has an
"Attribution Required" license. But, these "tools" do not follow these
licenses and the required.Therefore, there is no legally possible way to allow AI/LLM
contributions into the PHP source code.cheers,
Derick
I understand you have a point from the legal perspective, but as a thought
experiment we can consider any human-produced contribution potentially
tainted with lack of attribution under the same scrutiny, but it wouldn't
ever matter.
I definitely don't want to be debating in favor of AI use, the accelerated
method of burning down the planet or even how OSS is being bombarded by
extremely low quality AI-driven contributions. However, I don't think it's
in the spirit of OSS, the RFC nor PHP's best interest to debate AI like
that on a specific RFC from an author that is known for high quality OSS
contributions. Make an RFC and ban any use of AI on the PHP project for all
I care, but let's aim to be fair with the RFC being proposed as any other
RFC while such a rule/guideline doesn't exist.
--
Marco Deleu
Hi
Am 2026-01-22 16:54, schrieb Derick Rethans:
I read in the linked PR:
"Team work with Claude Code opus 4.5 💪"
This makes me instantly want to vote no to this.
What is being voted on as part of an RFC is the “concept”, not the
specific implementation. Having an implementation available is often
helpful to evaluate the feasibility of a concept and to figure out edge
cases, but it is possible and regularly happens that the implementation
changes quite a bit as part of the code review of the implementation. In
fact for my own RFCs, I often have a fairly sloppy “PoC” implementation
that I spend the time to clean up if / when I'm reasonably confident
that the RFC will pass to avoid doing needless work.
Or in this specific instance if the use of AI-assistance in the code is
considered a problem, it would be possible for someone who is more
familiar with the engine than Nicolas to do a “clean room”
implementation based on the semantics outlined in the RFC.
The RFC text should be judged on its own merit and should stand on its
own, such that any “sufficiently capable” developer would be able to
create the implementation - incl. all possible edge cases - based on the
specification in the RFC text alone.
Best regards
Tim Düsterhus
Dear all,
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignAs a quick intro, my motivation for that RFC is that I find it quite
annoying that readonly properties play badly with CPP (constructor
property promotion).Doing simple processing of any argument before assigning it to a
readonly property forces opting out of CPP.This RFC would allow setting once a readonly property in the body of a
constructor after the property was previously (and implicitly) set
using CPP.This allows keeping property declarations in their compact form while
still enabling validation, normalization, or conditional initialization.Cheers,
Nicolas
I can see the benefit of this, though I do have some concerns.
The reassignment must occur directly in the constructor body of the declaring class (not via method calls, closures, or other indirect means)
This could be an issue. I understand the argument for it, but for objects designed to be both constructed directly and deserialized the constructor may not always be called. A common solution is to move the shared logic out to a private method, say validate(), and then call validate() from both __construct() and __unserialize() (or the equivalent for a particular serializer). That would no longer be possible with this limitation, thus requiring duplication of code.
Child classes cannot reassign parent's promoted readonly properties
Why?
All other readonly semantics remain unchanged (no modification outside constructor, no unsetting, etc.)
The "no modification outside constructor" is not part of the language semantics. It is a recommended practice invented by SA tools.
I also share Derick's disdain for code produced by Grand Theft Autocomplete, and the legal risks therein.
--Larry Garfield
Hi
Am 2026-01-22 16:33, schrieb Nicolas Grekas:
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassign
Thank you. I have taken a look and have the following notes (for now):
- In the Problem Statement: “Option 2: Use default parameter
expressions (limited):”
The example seems incorrect to me, particularly the “// Cannot use $x in
default expression for $x” comment doesn't make sense. Can you check you
pasted in the correct snippet?
- Within the proposal: “The reassignment must occur directly in the
constructor body of the declaring class (not via method calls, closures,
or other indirect means)”
I believe this is inconsistent with __clone() where the readonly
property remains unlocked until the end of __clone() (and is then
locked).
I'm seeing it is explained further below as “This restriction exists
because the check verifies that the current executing function is the
constructor of the declaring class. When a method or closure executes,
the current function changes, even if it was called from the
constructor”, which effectively means that you defined the semantics
based on the implementation instead of the other way around, which I
consider problematic from a language design PoV. I'm positive it is
possible to find a better implementation here.
- Within the “RFC Impact” section you removed the “Ecosystem”
subsection from the template.
I believe mentioning the ecosystem impact is relevant here. This change
will likely require adjustments to static analysis tools and IDEs to not
point out the now-valid assignment as an error.
- As per the updated RFC policy.
Please already include the (closed) voting doodle in the RFC so there is
no ambiguity here. Don't forget to include the “Abstain” option. My
suggested title would just be using the RFC title followed by a
questionmark :-)
And please add a link to the list archives to the References section
(it's required per the policy and useful for future research). For your
convenience, the correct link is this:
https://news-web.php.net/php.internals/129851
Best regards
Tim Düsterhus
Thanks Tim, Larry,
Le jeu. 22 janv. 2026 à 17:21, Tim Düsterhus tim@bastelstu.be a écrit :
Hi
Am 2026-01-22 16:33, schrieb Nicolas Grekas:
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignThank you. I have taken a look and have the following notes (for now):
- In the Problem Statement: “Option 2: Use default parameter
expressions (limited):”The example seems incorrect to me, particularly the “// Cannot use $x in
default expression for $x” comment doesn't make sense. Can you check you
pasted in the correct snippet?
- Within the proposal: “The reassignment must occur directly in the
constructor body of the declaring class (not via method calls, closures,
or other indirect means)”I believe this is inconsistent with
__clone()where the readonly
property remains unlocked until the end of__clone()(and is then
locked).I'm seeing it is explained further below as “This restriction exists
because the check verifies that the current executing function is the
constructor of the declaring class. When a method or closure executes,
the current function changes, even if it was called from the
constructor”, which effectively means that you defined the semantics
based on the implementation instead of the other way around, which I
consider problematic from a language design PoV. I'm positive it is
possible to find a better implementation here.
- Within the “RFC Impact” section you removed the “Ecosystem”
subsection from the template.I believe mentioning the ecosystem impact is relevant here. This change
will likely require adjustments to static analysis tools and IDEs to not
point out the now-valid assignment as an error.
- As per the updated RFC policy.
Please already include the (closed) voting doodle in the RFC so there is
no ambiguity here. Don't forget to include the “Abstain” option. My
suggested title would just be using the RFC title followed by a
questionmark :-)And please add a link to the list archives to the References section
(it's required per the policy and useful for future research). For your
convenience, the correct link is this:
https://news-web.php.net/php.internals/129851
RFC text updated to account for your comments Tim, good catch and thanks
for the help around RFC processes.
About the assignment rule, Larry and you have the same reaction, so let me
take this as a good description of the most expected behavior by the
community ;-)
I made the more restricted rule because I thought I should start with the
stricter rule, and I get that would also be surprising somehow, so let's
relax that.
PR (and RFC) updated with the new logic, similar to __clone (and as boring
as it can be ;P )
Cheers,
Nicolas
Thanks Tim, Larry,
Le jeu. 22 janv. 2026 à 17:21, Tim Düsterhus tim@bastelstu.be a écrit :
Hi
Am 2026-01-22 16:33, schrieb Nicolas Grekas:
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignThank you. I have taken a look and have the following notes (for now):
- In the Problem Statement: “Option 2: Use default parameter
expressions (limited):”The example seems incorrect to me, particularly the “// Cannot use $x in
default expression for $x” comment doesn't make sense. Can you check you
pasted in the correct snippet?
- Within the proposal: “The reassignment must occur directly in the
constructor body of the declaring class (not via method calls, closures,
or other indirect means)”I believe this is inconsistent with
__clone()where the readonly
property remains unlocked until the end of__clone()(and is then
locked).I'm seeing it is explained further below as “This restriction exists
because the check verifies that the current executing function is the
constructor of the declaring class. When a method or closure executes,
the current function changes, even if it was called from the
constructor”, which effectively means that you defined the semantics
based on the implementation instead of the other way around, which I
consider problematic from a language design PoV. I'm positive it is
possible to find a better implementation here.
- Within the “RFC Impact” section you removed the “Ecosystem”
subsection from the template.I believe mentioning the ecosystem impact is relevant here. This change
will likely require adjustments to static analysis tools and IDEs to not
point out the now-valid assignment as an error.
- As per the updated RFC policy.
Please already include the (closed) voting doodle in the RFC so there is
no ambiguity here. Don't forget to include the “Abstain” option. My
suggested title would just be using the RFC title followed by a
questionmark :-)And please add a link to the list archives to the References section
(it's required per the policy and useful for future research). For your
convenience, the correct link is this:
https://news-web.php.net/php.internals/129851RFC text updated to account for your comments Tim, good catch and
thanks for the help around RFC processes.About the assignment rule, Larry and you have the same reaction, so let
me take this as a good description of the most expected behavior by the
community ;-)
I made the more restricted rule because I thought I should start with
the stricter rule, and I get that would also be surprising somehow, so
let's relax that.PR (and RFC) updated with the new logic, similar to __clone (and as
boring as it can be ;P )Cheers,
Nicolas
Boring is good in this case. :-) I like the updates. I only have two remaining quibbles.
All other readonly semantics remain unchanged (no modification outside constructor, no unsetting, etc.)
As previously stated, "no modification outside constructor" is not, and has never been, part of the language semantics of readonly. In fact, the RFC has been updated now such that updates outside of the constructor are allowed, provide the constructor is in the call stack. Please remove that clause, as it is incorrect.
And the LLM question, which warrants a separate discussion, I wager, and is not an issue of the RFC text.
--Larry Garfield
Le ven. 23 janv. 2026 à 16:59, Larry Garfield larry@garfieldtech.com a
écrit :
Thanks Tim, Larry,
Le jeu. 22 janv. 2026 à 17:21, Tim Düsterhus tim@bastelstu.be a écrit
:Hi
Am 2026-01-22 16:33, schrieb Nicolas Grekas:
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignThank you. I have taken a look and have the following notes (for now):
- In the Problem Statement: “Option 2: Use default parameter
expressions (limited):”The example seems incorrect to me, particularly the “// Cannot use $x
in
default expression for $x” comment doesn't make sense. Can you check
you
pasted in the correct snippet?
- Within the proposal: “The reassignment must occur directly in the
constructor body of the declaring class (not via method calls,
closures,
or other indirect means)”I believe this is inconsistent with
__clone()where the readonly
property remains unlocked until the end of__clone()(and is then
locked).I'm seeing it is explained further below as “This restriction exists
because the check verifies that the current executing function is the
constructor of the declaring class. When a method or closure executes,
the current function changes, even if it was called from the
constructor”, which effectively means that you defined the semantics
based on the implementation instead of the other way around, which I
consider problematic from a language design PoV. I'm positive it is
possible to find a better implementation here.
- Within the “RFC Impact” section you removed the “Ecosystem”
subsection from the template.I believe mentioning the ecosystem impact is relevant here. This change
will likely require adjustments to static analysis tools and IDEs to
not
point out the now-valid assignment as an error.
- As per the updated RFC policy.
Please already include the (closed) voting doodle in the RFC so there
is
no ambiguity here. Don't forget to include the “Abstain” option. My
suggested title would just be using the RFC title followed by a
questionmark :-)And please add a link to the list archives to the References section
(it's required per the policy and useful for future research). For your
convenience, the correct link is this:
https://news-web.php.net/php.internals/129851RFC text updated to account for your comments Tim, good catch and
thanks for the help around RFC processes.About the assignment rule, Larry and you have the same reaction, so let
me take this as a good description of the most expected behavior by the
community ;-)
I made the more restricted rule because I thought I should start with
the stricter rule, and I get that would also be surprising somehow, so
let's relax that.PR (and RFC) updated with the new logic, similar to __clone (and as
boring as it can be ;P )Cheers,
NicolasBoring is good in this case. :-) I like the updates. I only have two
remaining quibbles.All other readonly semantics remain unchanged (no modification outside
constructor, no unsetting, etc.)As previously stated, "no modification outside constructor" is not, and
has never been, part of the language semantics of readonly. In fact, the
RFC has been updated now such that updates outside of the constructor are
allowed, provide the constructor is in the call stack. Please remove that
clause, as it is incorrect.
How would you phrase this?
To me, point 3 above makes this clear: "The reassignment must occur while a
constructor of the object is on the call stack (methods and closures called
from the constructor are allowed)"
Then, point 7: "All other readonly semantics remain unchanged (no
modification outside constructor, no unsetting, etc.)" has enough context
to me to be clear.
No?
Boring is good in this case. :-) I like the updates. I only have two remaining quibbles.
All other readonly semantics remain unchanged (no modification outside constructor, no unsetting, etc.)
As previously stated, "no modification outside constructor" is not, and has never been, part of the language semantics of readonly. In fact, the RFC has been updated now such that updates outside of the constructor are allowed, provide the constructor is in the call stack. Please remove that clause, as it is incorrect.
How would you phrase this?
To me, point 3 above makes this clear: "The reassignment must occur
while a constructor of the object is on the call stack (methods and
closures called from the constructor are allowed)"
Then, point 7: "All other readonly semantics remain unchanged (no
modification outside constructor, no unsetting, etc.)" has enough
context to me to be clear.No?
There's a very subtle caveat here. Readonly properties that are not yet initialized can be set from anywhere, not just the constructor. That is the language semantic, regardless of what the PHPStan/Psalm authors think. :-)
In this particular case, because the property is being set in the constructor preamble, essentially, it cannot then be re-assigned... EXCEPT in the constructor due to this RFC. But that's a subtle, easy to miss caveat. Hence why I'd prefer wording that doesn't imply (to those that don't catch that subtlety) that the language doesn't allow readonly to be assigned outside of the constructor.
This is a particular pet peeve of mine because I have very good use cases for assigning to a readonly property outside of the constructor, but always therefore have to disable that check in PHPStan as a result. Hence why I harp on it so much. :-)
--Larry Garfield
Hi Larry,
Le dim. 25 janv. 2026 à 19:53, Larry Garfield larry@garfieldtech.com a
écrit :
Boring is good in this case. :-) I like the updates. I only have two
remaining quibbles.All other readonly semantics remain unchanged (no modification
outside constructor, no unsetting, etc.)As previously stated, "no modification outside constructor" is not, and
has never been, part of the language semantics of readonly. In fact, the
RFC has been updated now such that updates outside of the constructor are
allowed, provide the constructor is in the call stack. Please remove that
clause, as it is incorrect.How would you phrase this?
To me, point 3 above makes this clear: "The reassignment must occur
while a constructor of the object is on the call stack (methods and
closures called from the constructor are allowed)"
Then, point 7: "All other readonly semantics remain unchanged (no
modification outside constructor, no unsetting, etc.)" has enough
context to me to be clear.No?
There's a very subtle caveat here. Readonly properties that are not yet
initialized can be set from anywhere, not just the constructor. That is
the language semantic, regardless of what the PHPStan/Psalm authors think.
:-)In this particular case, because the property is being set in the
constructor preamble, essentially, it cannot then be re-assigned... EXCEPT
in the constructor due to this RFC. But that's a subtle, easy to miss
caveat. Hence why I'd prefer wording that doesn't imply (to those that
don't catch that subtlety) that the language doesn't allow readonly to be
assigned outside of the constructor.This is a particular pet peeve of mine because I have very good use cases
for assigning to a readonly property outside of the constructor, but always
therefore have to disable that check in PHPStan as a result. Hence why I
harp on it so much. :-)
I updated the text to make this more clear, thanks for the suggestion!
On Thu, Jan 22, 2026 at 4:39 PM Nicolas Grekas
nicolas.grekas+php@gmail.com wrote:
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassign
Thank you very much for the RFC. I really enjoyed reading it; clearly
explained, easy to read, and with a good focus on laying out how
everything works and considering edge cases. Especially the working
examples around "Child Classes Can Reassign Parent Properties" have
been great to read.
It's delightful that you were able to provide a PoC implementation for
me to check and answer the remaining questions I had.
Great to see more people being able to modify php-src to this scope.
I think this makes sense, aligns behavior with clone, and patches up
one edge case with using CPP over regular properties, easing
refactoring.
While this is not a problem I, personally, ran into, it makes sense to
me, and given any upcoming insights in the discussion, I'm in favor of
it.
Thank you,
Volker
Le 22 janv. 2026 à 16:33, Nicolas Grekas nicolas.grekas+php@gmail.com a écrit :
Dear all,
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignAs a quick intro, my motivation for that RFC is that I find it quite annoying that readonly properties play badly with CPP (constructor property promotion).
Doing simple processing of any argument before assigning it to a readonly property forces opting out of CPP.
This RFC would allow setting once a readonly property in the body of a constructor after the property was previously (and implicitly) set using CPP.
This allows keeping property declarations in their compact form while still enabling validation, normalization, or conditional initialization.
Cheers,
Nicolas
Hi,
I am reserved about the proposal, because this style of using CPP and processing the value after the fact tends to favour brevity at the expense of precision and clarity. Let’s illustrate that with two examples from the RFC. First:
class Config {
public function __construct(
public readonly ?string $cacheDir = null,
) {
$this->cacheDir ??= `sys_get_temp_dir()` . '/app_cache';
}
}
As of today you can write:
class Config {
public readonly string $cacheDir;
public function __construct(
?string $cacheDir = null,
) {
$this->cacheDir = $cacheDir ??= `sys_get_temp_dir()` . '/app_cache';
}
}
Note that the property is marked as non-nullable, a precision that may be useful for both programmers and static analysers. With your proposal, there is no way to keep this information.
The second example is similar:
class User {
public function __construct(
public readonly string $email,
) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
$this->email = strtolower($email); // Normalize
}
}
As of today, it can be written as:
class User {
/** @var non-empty-string & lowercase-string */
public readonly string $email;
public function __construct(
string $email,
) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
$this->email = strtolower($email); // Normalize
}
}
With your proposal, there is no obvious way to keep the additional information provided in the phpdoc. Maybe we could imagine something like that:
class User {
/**
* @param string $email the e-mail address as provided
*/
public function __construct(
/** @var non-empty-string & lowercase-string the normalised e-mail address */
string $email,
) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
$this->email = strtolower($email); // Normalize
}
}
but it is obviously clearer (at least to my eyes) to keep the property and the constructor parameter separate.
One additional thought: Readonly properties carry a constraint that is annoying at first, but that is finally beneficial for the clarity of code that is written. When initialising such a property with something more complex than what can be comfortably written in a single expression, I am forced to write the intermediate results in a temporary variable and to assign the final value to the property at the end of the process, instead of transforming gradually the value of the property. The resulting code is a few lines longer, but it is no less clear, even it is often clearer, because it is obvious that this specific assignment supplies the final value of the property, and there is no need to look further down to see whether the value will undergo some additional transformations. As of today, this “final assignment” may be part of the constructor signature; with this RFC implemented, one can no longer know at a glance whether this assignment is “final”.
(Also I sympathise with Larry: rigid coding styles and static analysers’ promoted “good practices” add problematic limitations that are not part of the semantics of language. I prefer disabling checks in PHPStan rather than downgrading to non-safe mutable properties and/or writing getters around them.)
—Claude
Hi Claude,
Le mer. 28 janv. 2026 à 19:53, Claude Pache claude.pache@gmail.com a
écrit :
Le 22 janv. 2026 à 16:33, Nicolas Grekas nicolas.grekas+php@gmail.com a
écrit :Dear all,
Here is a new RFC for you to consider:
https://wiki.php.net/rfc/promoted_readonly_constructor_reassignAs a quick intro, my motivation for that RFC is that I find it quite
annoying that readonly properties play badly with CPP (constructor property
promotion).Doing simple processing of any argument before assigning it to a readonly
property forces opting out of CPP.This RFC would allow setting once a readonly property in the body of a
constructor after the property was previously (and implicitly) set using
CPP.This allows keeping property declarations in their compact form while
still enabling validation, normalization, or conditional initialization.Cheers,
NicolasHi,
I am reserved about the proposal, because this style of using CPP and
processing the value after the fact tends to favour brevity at the expense
of precision and clarity. Let’s illustrate that with two examples from the
RFC. First:class Config { public function __construct( public readonly ?string $cacheDir = null, ) { $this->cacheDir ??= `sys_get_temp_dir()` . '/app_cache'; } }As of today you can write:
class Config { public readonly string $cacheDir; public function __construct( ?string $cacheDir = null, ) { $this->cacheDir = $cacheDir ??= `sys_get_temp_dir()` . '/app_cache'; } }Note that the property is marked as non-nullable, a precision that may be
useful for both programmers and static analysers. With your proposal, there
is no way to keep this information.The second example is similar:
class User { public function __construct( public readonly string $email, ) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidArgumentException('Invalid email'); } $this->email = strtolower($email); // Normalize } }As of today, it can be written as:
class User { /** @var non-empty-string & lowercase-string */ public readonly string $email; public function __construct( string $email, ) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidArgumentException('Invalid email'); } $this->email = strtolower($email); // Normalize } }With your proposal, there is no obvious way to keep the additional
information provided in the phpdoc. Maybe we could imagine something like
that:class User { /** * @param string $email the e-mail address as provided */ public function __construct( /** @var non-empty-string & lowercase-string the normalised e-mail address */ string $email, ) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidArgumentException('Invalid email'); } $this->email = strtolower($email); // Normalize } }but it is obviously clearer (at least to my eyes) to keep the property and
the constructor parameter separate.One additional thought: Readonly properties carry a constraint that is
annoying at first, but that is finally beneficial for the clarity of code
that is written. When initialising such a property with something more
complex than what can be comfortably written in a single expression, I am
forced to write the intermediate results in a temporary variable and to
assign the final value to the property at the end of the process, instead
of transforming gradually the value of the property. The resulting code is
a few lines longer, but it is no less clear, even it is often clearer,
because it is obvious that this specific assignment supplies the final
value of the property, and there is no need to look further down to see
whether the value will undergo some additional transformations. As of
today, this “final assignment” may be part of the constructor signature;
with this RFC implemented, one can no longer know at a glance whether this
assignment is “final”.(Also I sympathise with Larry: rigid coding styles and static analysers’
promoted “good practices” add problematic limitations that are not part of
the semantics of language. I prefer disabling checks in PHPStan rather than
downgrading to non-safe mutable properties and/or writing getters around
them.)
Thank you for the thoughtful feedback. You raise valid points about type
precision and PHPDoc annotations being harder to express with CPP.
I've added a "Design Considerations" section to the RFC acknowledging these
tradeoffs and clarifying when traditional declaration remains preferable
(type narrowing, detailed annotations, complex initialization) vs. when CPP
- reassignment fits well (simple transformations like trim/lowercase,
validation with fallback).
The key point is: this RFC adds an option, it doesn't mandate any style. If
"final at declaration" clarity matters for a specific property, traditional
declaration remains available.
Regarding the "final assignment" concern: an earlier iteration considered
restricting reassignment to only the constructor body (no other methods
could reassign), but this was ruled out, at least for consistency with
__clone().
Cheers,
Nicolas
Hey Nicolas,
Thank you for the thoughtful feedback. You raise valid points about
type precision and PHPDoc annotations being harder to express with CPP.I've added a "Design Considerations" section to the RFC acknowledging
these tradeoffs and clarifying when traditional declaration remains
preferable (type narrowing, detailed annotations, complex
initialization) vs. when CPP + reassignment fits well (simple
transformations like trim/lowercase, validation with fallback).The key point is: this RFC adds an option, it doesn't mandate any
style. If "final at declaration" clarity matters for a specific
property, traditional declaration remains available.
I do generally sympathize with Claudes viewpoint here.
While it's true that the RFC only adds a way how to write code, it also
removes the currently valid assumption, that, whenever a readonly
property is declared in a constructor arg, the arg will be exactly
identical to the passed value.
I will likely vote abstain on this RFC. I'm on the fence between "we
should have this" (I can see that not repeating the type and variable
name has some benefits) and "this muddies the readonly semantics".
Bob