> The original motivation was, IIRC, to initialize class constants with an 
> expression.
> Following KISS, I feel we should constrain our efforts to that scope, and 
> that's how I voted:
> "Yes" on class constants and static members, "No" on everything else.

I'd also personally found the `static $x = null; if ($x === null) { $x = 
some_fn(); }` pattern inconvenient and wanted that to be just `static $x = 
some_fn();` to make the initial value `some_fn()` if possible. It also seemed 
more readable (e.g. doesn't matter if some_fn() can be constant).

My personal use case for parameter defaults and global constants isn't as 
strong (especially with define()),
but it's still something I'd want.

- I'd be able to use `private const FOO_DEFAULT = array_keys(...); function 
foo($x = FOO_DEFAULT) {}` if constants did pass, so that's less off a concern, 
and ensures&makes clear that the expression is only evaluated once, so it might 
be a better place to start with.

> As for implementation, we must manage the complexity.
> I'm a hard "No" on restricting use to an arbitrary, variable list of blessed 
> functions.
> It's a dev UX nightmare to include a bevy of array_* functions but no str* 
> functions.

If the RFC succeeded with a whitelist, I'd planned to create RFCs to add to the 
whitelist.
Locale dependency of string functions was the reason for leaving it out 
initially, since that may also be a hard "no" for others.

> Consequently, the only way to safely initialize class constants and static 
> members is at run-time, and I can only think of one way to do it.
> Apologies if this has already been suggested: taking a cue from C#, a static 
> class constructor ([1]) 
> would allow us to have expression-initialized constants and static members.
> <?php
> class Config {
>     public const URL = null; // compile time initialization
>     protected static $mtime = null; // compile time initialization
>     private static function __constructStatic() {
>         $env = json_decode(file_get_contents('config.json'));
>         self::URL = $env->url;
>         self::$mtime = filemtime('config.json');
>    }
>    public function reload() {
>        if (self::$mtime < filemtime('config.json'))
>            self::__constructStatic();
>        }
>    }
> }
> 
> echo Config::URL; // assert: runtime has already called _constructStatic
> $config = new Config; // assert: __constructStatic called only once by runtime
> $config->reload(); // instance may call its own static constructor
?>

This seems to allow the same functionality my RFC would allow, in a slightly 
different way.
I didn't go with that syntax because it'd move the values of the 
constants/properties away from the declaration.
Also, if `json_decode()` threw, then there would never be a way for a PHP 
implementation to initialize `self::$mtime` in that example, even though 
they're unrelated in how they're initialized there.
Allowing calling `__constructStatic` multiple times (thus assigning to the 
**const** `self::URL` multiple times) would be a significant change to php 
internals, and out of the scope of this RFC

https://wiki.php.net/rfc/calls_in_constant_expressions_poll ("Put the RFC(Poll) 
URL into all your replies.")

- Tyson
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to