[RFC][Vote announcement] Arbitrary static variable initializers

php.internals

Ilija Tovilo

3 years ago
Hi everybody It's been a while since I've announced this RFC. https://wiki.php.net/rfc/arbitrary_static_variable_initializers https://externals.io/message/118976 There haven't been many responses, so I'd like to put this to a vote early next week. Ilija

Alain Williams

3 years ago
On Wed, Mar 15, 2023 at 01:02:04PM +0100, Ilija Tovilo wrote:
> Hi everybody > > It's been a while since I've announced this RFC. > https://wiki.php.net/rfc/arbitrary_static_variable_initializers > https://externals.io/message/118976 > > There haven't been many responses, so I'd like to put this to a vote > early next week.
Could I suggest that you make something like the following throw an error: function foo($i) { static $a = $b + 1; static $b = $i; } You could try to reorder but what if the second static had been: static $b = $i + $a; Yes: stupid, but someone will try it.
-- Alain Williams Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer. +44 (0) 787 668 0256 https://www.phcomp.co.uk/ Parliament Hill Computers Ltd. Registration Information: https://www.phcomp.co.uk/Contact.html #include <std_disclaimer.h>

Ilija Tovilo

3 years ago
Hi Alain
> > https://wiki.php.net/rfc/arbitrary_static_variable_initializers > > https://externals.io/message/118976 > > Could I suggest that you make something like the following throw an error: > > function foo($i) { > static $a = $b + 1; > static $b = $i; > } > > You could try to reorder but what if the second static had been: > > static $b = $i + $a; > > Yes: stupid, but someone will try it.
With this RFC static variables are evaluated in the normal order of execution. The first statement will throw an undefined variable warning and result in 1. The second one will be initialized to whatever $i contains. This is consistent with non-static variables. Ilija

Tim Düsterhus

3 years ago
Hi On 3/15/23 13:02, Ilija Tovilo wrote:
> It's been a while since I've announced this RFC. > https://wiki.php.net/rfc/arbitrary_static_variable_initializers > https://externals.io/message/118976 > > There haven't been many responses, so I'd like to put this to a vote > early next week. >
There is an unresolved "question":
> Side note: It's been suggested that expressions that can be evaluated constantly continue to do so. This would mean that some expressions in getStaticVariables are evaluated and some are not. The upside is that this would avoid the backward incompatibility. I will check if this is technically feasible.
Best regards Tim Düsterhus

Ilija Tovilo

3 years ago
Hi Tim
> > https://wiki.php.net/rfc/arbitrary_static_variable_initializers > > https://externals.io/message/118976 > > There is an unresolved "question": > > > Side note: It's been suggested that expressions that can be evaluated constantly continue to do so. This would mean that some expressions in getStaticVariables are evaluated and some are not. The upside is that this would avoid the backward incompatibility. I will check if this is technically feasible.
Ah, thanks for catching this. This has been partially implemented. PHP will attempt to evaluate the constant expression at compile time. If successful, the value will continue to be available from ReflectionFunction::getStaticVariables() right away. Only when the expression isn't known at compile time (including class constants from other files) will it contain null until the function is called. This reduces the BC incompatibility but doesn't completely avoid it. Ilija

Tim Düsterhus

3 years ago
Hi On 3/15/23 18:21, Ilija Tovilo wrote:
>>> https://wiki.php.net/rfc/arbitrary_static_variable_initializers >>> https://externals.io/message/118976 >> >> There is an unresolved "question": >> >>> Side note: It's been suggested that expressions that can be evaluated constantly continue to do so. This would mean that some expressions in getStaticVariables are evaluated and some are not. The upside is that this would avoid the backward incompatibility. I will check if this is technically feasible. > > Ah, thanks for catching this. This has been partially implemented. PHP > will attempt to evaluate the constant expression at compile time. If > successful, the value will continue to be available from > ReflectionFunction::getStaticVariables() right away. Only when the > expression isn't known at compile time (including class constants from > other files) will it contain null until the function is called. This > reduces the BC incompatibility but doesn't completely avoid it. >
Using Alain's example of static variables that depend on each other. For the following: function foo() { static $a = 0; static $b = $a + 1; } The value of '$a' is known at compile time. Is the value of '$b' also known at compile time? It might make sense to include that as an explicit example in the RFC (examples are cheap). Best regards Tim Düsterhus

Ilija Tovilo

3 years ago
Hi Tim
> Using Alain's example of static variables that depend on each other. For > the following: > > function foo() { > static $a = 0; > static $b = $a + 1; > } > > The value of '$a' is known at compile time. Is the value of '$b' also > known at compile time? It might make sense to include that as an > explicit example in the RFC (examples are cheap).
Interesting thought. $a's initial value is known at compile time, but $b's isn't because it doesn't depend on $a's runtime value by the time it reaches $b's initialization. This value could change between $a and $b's initialization through direct assignment, by-ref modification, or even access by-name which is not easily detectable. I've added a section to the RFC to explain how this works in more detail. https://wiki.php.net/rfc/arbitrary_static_variable_initializers#what_initializers_are_known_at_compile-time Let me know if anything is still unclear. Ilija

Tim Düsterhus

3 years ago
Hi Thank you, I've had another read through the RFC. On 3/16/23 12:51, Ilija Tovilo wrote:
> Let me know if anything is still unclear. >
Isn't the destructor+exception example misleading? In that case the initial value of '$x' is constant, thus it should always be known to reflection, no? Should the example look like this:
> function foo($y) { > $x = new Foo(); > static $x = $y; > } > > try { > foo(42); > } catch (Exception) {}
? Side-Note: I find the behavior of static variables that do not overwrite existing variables extremely confusing, even without this RFC: https://3v4l.org/ApIcA. Anyone who doesn't define them at the very top of a function deserves a special place in hell :-) Best regards Tim Düsterhus

Ilija Tovilo

3 years ago
Hi Tim
> Isn't the destructor+exception example misleading? In that case the > initial value of '$x' is constant, thus it should always be known to > reflection, no? > > Should the example look like this: > > > function foo($y) { > > $x = new Foo(); > > static $x = $y; > > } > > > > try { > > foo(42); > > } catch (Exception) {} > > ?
Yes, your example makes more sense. In my old example the value of the static variable was already assigned so didn't prove the point it was trying to make. I adjusted the example in the RFC. Thanks!

Tim Düsterhus

3 years ago
Hi On 3/17/23 14:32, Ilija Tovilo wrote:
> Yes, your example makes more sense. In my old example the value of the > static variable was already assigned so didn't prove the point it was > trying to make. I adjusted the example in the RFC.
Okay, I believe that resolves all the remarks I ha(ve|d). Best regards Tim Düsterhus

Alexandru Pătrănescu

3 years ago
On Wed, Mar 15, 2023, 14:02 Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
> Hi everybody > > It's been a while since I've announced this RFC. > https://wiki.php.net/rfc/arbitrary_static_variable_initializers > https://externals.io/message/118976 > > There haven't been many responses, so I'd like to put this to a vote > early next week. > > Only a small thing in the example for
"ReflectionFunction::getStaticVariables()" section. I expect the third var_dump to print 1 also since the static statement is not going to be executed again when calling foo(2). Am I wrong? Regards, Alex

Ilija Tovilo

3 years ago
Hi Alexandru
>> https://wiki.php.net/rfc/arbitrary_static_variable_initializers >> https://externals.io/message/118976 >> >> There haven't been many responses, so I'd like to put this to a vote >> early next week. >> > Only a small thing in the example for "ReflectionFunction::getStaticVariables()" section. > I expect the third var_dump to print 1 also since the static statement is not going to be executed again when calling foo(2). > Am I wrong?
Nope, you're absolutely right. That was a mistake on my part. I adjusted the example, thanks for pointing it out! Ilija @Alexandru Sorry for the duplicate mail, I forgot to press Reply All.