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
Heyo,
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
Heyo,
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
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
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
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
What's convenient about
Foo::{$bar}
vsconstant(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.
What's convenient about
Foo::{$bar}
vsconstant(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.--
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).
What's convenient about
Foo::{$bar}
vsconstant(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.
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.
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 usingconstant()
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
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.
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
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
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
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.
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
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.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
Hi Nicolas
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