Hi Joshua
First of all, thank you for your proposal and the effort you've put into
the implementation.
I'm skeptical about the usefulness of local immutability as a whole. I
personally don't recognize local mutability as a significant source of
bugs, contrary to action at a distance. Putting that aside:
I understand your implementation is a proof-of-concept, but the approach
looks wrong to me. I think if local immutability is added, it should
mostly be a compile-time concept. The implementation currently add a new
opcode for readonly assignment, and touches all existing assignments to
add immutability checks. This seems mostly unnecessary with few
exceptions (those being var-vars, globals, extract, pass-by-reference
reference promotion, etc.), as the compiler can assert that the variable
being assigned to isn't marked as readonly. The implementation shows an
instruction count increase of 5.2%, 1.3% and 2.1% for Zend/bench.php,
Symfony Demo and Wordpress, respectively. That should mostly go away
with a compile time approach.
There are likely also some limitations to the compile-time approach:
- Without runtime tracking of readonly (and the concept of block
scoping) every variable name could only be declared once in a function. - Disallowing
$readonly['foo'] = 'bar';at compile-time will
incorrectly restrict ArrayOffset, which I personally find acceptable. - Similar to the above, compile-time checks are insufficient for future
value types. [1]$readonly->foo = 'bar';should fail if $readonly is a
value type, which will necessarily require additional runtime checks.
This is further complicated by$readonly->foo->bar = 'baz';, which
should fail only if $readonly->foo itself is also a value type. Given
this issue applies to arbitrarily long chains, I don't know how this
could be solved.
For the reasons mentioned, I don't think I'd support this RFC in any
form. Nonetheless, I appreciate the care that has gone both into the RFC
and implementation.
Ilija
Hi
Am 2026-02-25 15:41, schrieb Ilija Tovilo:
- Without runtime tracking of readonly (and the concept of block
scoping) every variable name could only be declared once in a function.
After thinking about the RFC for a few days, Ilija is making a good
point here:
I find “block scoping” a necessary prerequisite to have local readonly
variables (and also local typed variables). Being able to define a
readonly variable within an if() and thus making it conditionally
readonly (or conditionally typed) is going to invite confusion. It is
the obviously correct behavior with the current semantics of PHP,
though.
I nevertheless appreciate the effort that went into the RFC, particular
with the attention to detail pointing out all “edge cases”. It made it
really easy to think about the proposal, because there was no need to
make assumptions about how it's supposed to work.
Best regards
Tim Düsterhus