[RFC][Dynamic class constant fetch]

php.internals

Ilija Tovilo

3 years ago
Hi everyone I'd like to propose a simple RFC to introduce looking up class constants by name. We have dedicated syntax for basically all other language constructs. This RFC aims to get rid of this seemingly arbitrary limitation. https://wiki.php.net/rfc/dynamic_class_constant_fetch Please let me know if you have any thoughts. Ilija

Marco Pivetta

3 years ago
Heyo, On Fri, 4 Nov 2022 at 15:26, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
> Hi everyone > > I'd like to propose a simple RFC to introduce looking up class > constants by name. We have dedicated syntax for basically all other > language constructs. This RFC aims to get rid of this seemingly > arbitrary limitation. > > https://wiki.php.net/rfc/dynamic_class_constant_fetch > > Please let me know if you have any thoughts. >
What's the problem with using `constant()` for this? Marco Pivetta https://twitter.com/Ocramius https://ocramius.github.io/

Larry Garfield

3 years ago
On Fri, Nov 4, 2022, at 9:31 AM, Marco Pivetta wrote:
> Heyo, > > On Fri, 4 Nov 2022 at 15:26, Ilija Tovilo <tovilo.ilija@gmail.com> wrote: > >> Hi everyone >> >> I'd like to propose a simple RFC to introduce looking up class >> constants by name. We have dedicated syntax for basically all other >> language constructs. This RFC aims to get rid of this seemingly >> arbitrary limitation. >> >> https://wiki.php.net/rfc/dynamic_class_constant_fetch >> >> Please let me know if you have any thoughts. >> > > What's the problem with using `constant()` for this? > > Marco Pivetta > > https://twitter.com/Ocramius > > https://ocramius.github.io/
As it says right in the RFC: // This: echo Foo::{$bar}; // is way more convenient than this mess: echo constant(Foo::class . '::' . $bar); This is something people have mentioned a number of times with enums and dynamic case references, and seems like a good small cleanup. --Larry Garfield

Marco Pivetta

3 years ago
On Fri, 4 Nov 2022 at 15:40, Larry Garfield <larry@garfieldtech.com> wrote:
> On Fri, Nov 4, 2022, at 9:31 AM, Marco Pivetta wrote: > > Heyo, > > > > On Fri, 4 Nov 2022 at 15:26, Ilija Tovilo <tovilo.ilija@gmail.com> > wrote: > > > >> Hi everyone > >> > >> I'd like to propose a simple RFC to introduce looking up class > >> constants by name. We have dedicated syntax for basically all other > >> language constructs. This RFC aims to get rid of this seemingly > >> arbitrary limitation. > >> > >> https://wiki.php.net/rfc/dynamic_class_constant_fetch > >> > >> Please let me know if you have any thoughts. > >> > > > > What's the problem with using `constant()` for this? > > > > Marco Pivetta > > > > https://twitter.com/Ocramius > > > > https://ocramius.github.io/ > > As it says right in the RFC: > > // This: > echo Foo::{$bar}; > > // is way more convenient than this mess: > echo constant(Foo::class . '::' . $bar); > > This is something people have mentioned a number of times with enums and > dynamic case references, and seems like a good small cleanup. >
What's convenient about `Foo::{$bar}` vs `constant(Foo::class . '::' . $bar)`? I'm a bit confused by this :| Is it the few keystrokes added? Marco Pivetta https://twitter.com/Ocramius https://ocramius.github.io/

Илья Сомов

3 years ago
> What's convenient about `Foo::{$bar}` vs `constant(Foo::class . '::' . > $bar)`? I'm a bit confused by this :| > > Is it the few keystrokes added?
Even if ignoring syntax / convenience bikeshedding, I find it a really valuable addition to the language self-consistency. It's symmetrical to the already existing syntax of dynamic property fetch and dynamic method calls. One could argue that it's dynamic, too much magic and bad, but then we should either deprecate those features, or if not, have this symmetry. The Principle of Least Amusement and human pattern recognition overall with thank you.

Flávio Heleno

3 years ago
On Fri, Nov 4, 2022 at 12:08 PM someniatko <someniatko@gmail.com> wrote:
> > What's convenient about `Foo::{$bar}` vs `constant(Foo::class . '::' . > > $bar)`? I'm a bit confused by this :| > > > > Is it the few keystrokes added? > > Even if ignoring syntax / convenience bikeshedding, I find it a really > valuable addition to the language self-consistency. It's symmetrical > to the already existing syntax of dynamic property fetch and dynamic > method calls. One could argue that it's dynamic, too much magic and > bad, but then we should either deprecate those features, or if not, > have this symmetry. The Principle of Least Amusement and human pattern > recognition overall with thank you. > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
I agree with @someniatko, it makes PHP more consistent, which IMHO is always positive and one of the usually criticized points (lack of consistency throughout parameter order, naming convention etc).

Weirdan

3 years ago
On Fri, Nov 4, 2022 at 10:49 AM Marco Pivetta <ocramius@gmail.com> wrote:
> What's convenient about `Foo::{$bar}` vs `constant(Foo::class . '::' . > $bar)`? I'm a bit confused by this :|
From the static analysis POV `Foo::{$bar}` is way better, as we can immediately see that the code is trying to access a constant of a specific class, and we can, e.g., flag those operations that did not validate that `$bar` actually exists as a Foo constant.

Ralf Lang

3 years ago
Hi Ilija, Am 04.11.2022 um 15:25 schrieb Ilija Tovilo:
> Please let me know if you have any thoughts. > > Ilija
That new way of accessing class constants dynamically does not really make things more readable for me. Maybe I just need to get used to it, but especially that last example would make my head spin without additional comments: Foo::{test('foo')}::{test('bar')}; Maybe I miss the use case. What kind of code would benefit from this? Wouldn't just using constant() for dynamically built constant strings be more legible? Maybe in a separate line? In the past I used a lot of flag constants backed by integers. A lot of these use cases have become classes/types in their own right since. When do you use these constants? Just my thoughts.

Larry Garfield

3 years ago
On Fri, Nov 4, 2022, at 9:45 AM, Ralf Lang wrote:
> Hi Ilija, > > Am 04.11.2022 um 15:25 schrieb Ilija Tovilo: >> Please let me know if you have any thoughts. >> >> Ilija > > That new way of accessing class constants dynamically does not really > make things more readable for me. Maybe I just need to get used to it, > but especially that last example would make my head spin without > additional comments: > > Foo::{test('foo')}::{test('bar')}; Maybe I miss the use case. What kind > of code would benefit > from this? Wouldn't just using constant() for dynamically built > constant > strings be more legible? Maybe in a separate line? In the past I used a > lot of flag constants backed by integers. A lot of these use cases have > become classes/types in their own right since. When do you use these > constants? Just my thoughts.
Dynamically building strings for syntax is almost never more legible. :-) I doubt you'd ever double them up the way some of the examples show. In practice, the single Class::{$const} or Enum::{$name} would be the most common uses, I predict, and those are way nicer to read than the 3x longer constant() with string concat. --Larry Garfield

Michał Brzuchalski

3 years ago
Hi Ilija, pt., 4 lis 2022, 15:26 użytkownik Ilija Tovilo <tovilo.ilija@gmail.com> napisał:
> Hi everyone > > I'd like to propose a simple RFC to introduce looking up class > constants by name. We have dedicated syntax for basically all other > language constructs. This RFC aims to get rid of this seemingly > arbitrary limitation. > > https://wiki.php.net/rfc/dynamic_class_constant_fetch
Can it be extended to non class constants and additionally deprecations plan for constant() function? I know it may not be the easiest but if we are about completeness and consistency I think coins the cleanup with planned standard library function removal would be complete. Cheers, Michał Marcin Brzuchalski

Nikita Popov

3 years ago
On Fri, Nov 4, 2022 at 3:26 PM Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
> Hi everyone > > I'd like to propose a simple RFC to introduce looking up class > constants by name. We have dedicated syntax for basically all other > language constructs. This RFC aims to get rid of this seemingly > arbitrary limitation. > > https://wiki.php.net/rfc/dynamic_class_constant_fetch > > Please let me know if you have any thoughts. >
The proposal looks reasonable to me. While I wouldn't expect this syntax to see much use, it does remove a syntactical inconsistency in the language.
> Order of execution
See https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html#writes-and-memory-safety for why the order of execution is the way it is. As class constants do not support writes, these concerns do not apply, and the "normal" order can be used (as you propose). Regards, Nikita

Ilija Tovilo

3 years ago
Hi everyone Sorry for the late reply. I won't waste too many lines on usefulness as it is highly subjective. The change will seem worth it to some people and not to others. IMO language consistency is important and mainly what I'm striving for. --- Hi Michał
> Can it be extended to non class constants and additionally deprecations plan for constant() function?
I'm not sure what that syntax would look like. {$foo} is not a viable option since it is ambiguous or rather would require arbitrary lookahead (i.e. {$foo;} is valid syntax today). A different syntax would be possible but inconsistent with the existing options. In any case, this would likely require its own RFC and should be discussed separately. --- Hi Nikita
> See https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html#writes-and-memory-safety for why the order of execution is the way it is. As class constants do not support writes, these concerns do not apply, and the "normal" order can be used (as you propose).
Thank you! I remembered discussing this back when implementing the nullsafe operator but was fuzzy on the details :) This makes more sense to me now. I tried to clarify in the RFC. Ilija

Ilija Tovilo

3 years ago
Hi everyone
> I'd like to propose a simple RFC to introduce looking up class > constants by name. We have dedicated syntax for basically all other > language constructs. This RFC aims to get rid of this seemingly > arbitrary limitation. > > https://wiki.php.net/rfc/dynamic_class_constant_fetch
Heads up: There hasn't been much discussion on this RFC in the last couple of weeks, thus I'd like to start the voting phase in the next couple of days. Ilija

Nicolas Grekas

3 years ago
Hi Ilija,
> I'd like to propose a simple RFC to introduce looking up class > > constants by name. We have dedicated syntax for basically all other > > language constructs. This RFC aims to get rid of this seemingly > > arbitrary limitation. > > > > https://wiki.php.net/rfc/dynamic_class_constant_fetch > > Heads up: There hasn't been much discussion on this RFC in the last > couple of weeks, thus I'd like to start the voting phase in the next > couple of days. >
Thanks for the reminder about this topic. I'm wondering about this:
> This RFC proposes no change in the interaction between class constant
fetches and the null-coalescing operator ??. That is, Foo::{$bar} ?? null; will throw an Error if the given constant does not exist. It would be possible to suppress this error as is done for other types of member accesses. However, it's not clear whether this is desirable, especially for explicit class constant fetches. This change can be made in the future with no backwards compatibility break. Since an argument in favor of the RFC is to replace a function call by native syntax, wouldn't it be desired to allow the same for checking the existence of a const? I'm thinking about defined(), which the ?? operator would nicely replace IMHO. Are there technical reasons to not do it in this RFC? If not, could this be considered? Thanks, Nicolas

Ilija Tovilo

3 years ago
Hi Nicolas
>> > https://wiki.php.net/rfc/dynamic_class_constant_fetch >> > > I'm wondering about this: > > > This RFC proposes no change in the interaction between class constant fetches and the null-coalescing operator ??. That is, Foo::{$bar} ?? null; will throw an Error if the given constant does not exist. It would be possible to suppress this error as is done for other types of member accesses. However, it's not clear whether this is desirable, especially for explicit class constant fetches. This change can be made in the future with no backwards compatibility break. > > Since an argument in favor of the RFC is to replace a function call by native syntax, wouldn't it be desired to allow the same for checking the existence of a const? I'm thinking about defined(), which the ?? operator would nicely replace IMHO. > > Are there technical reasons to not do it in this RFC? If not, could this be considered?
It's not a technical reason. I was specifically asked to propose an adjustment of interaction with ?? in a separate RFC because it is more controversial. To be precise, suppressing undefined member errors for `Foo::{$bar} ?? 'bar'` means we're also suppressing them for `Foo::BAR ?? 'bar'` (as we do for `$foo->bar ?? 'bar'`). Granted, we could make an exception here but I don't think that is a good idea in terms of consistency and user expectancy. FWIW, I still think this change is worth making and I'm planning on proposing this for PHP 8.3. I created a small proof of concept which seems to indicate this is indeed possible, but there are some details that need to be ironed out (like consistent isset/empty behavior, consistent error suppression when chaining, etc). Ilija