Re: [Discussion] Implicitly backed enums

From: Date: Thu, 23 May 2024 06:35:09 +0000
Subject: Re: [Discussion] Implicitly backed enums
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
On Wed, May 22, 2024 at 4:13 AM Larry Garfield <[email protected]> wrote:
>
> On Tue, May 21, 2024, at 6:47 PM, Bilge wrote:
> > On 22/05/2024 00:31, Larry Garfield wrote:
> >> I could see an argument for auto-populating the backing value off the enum name if
> >> it's not specified, something like this: enum Options: string {
> >>   case First; // This implicitly gets "First"
> >>   case Second = '2nd';
> >> }
> > This seems like a reasonable compromise. In this case, all I need to do
> > is change my enum to a backed enum (suffix : string) and I get the
> > benefits of implicit values. I still like the idea of the same being
> > possible for non-backed enums, though I imagine that is a product of my
> > naïveté, as I do not tend to think of things in the framing of
> > (de)serialization.
>
> Making it really hard and unnatural for people to use PHP enums as "cheap named
> strings/ints" is something we want to keep, because the whole value of enums is that they are
> their own separate type.  A Direction is not a string, it's not an int, it's not an array,
> it's not a Product, it's a Direction.  That's the end of it.  Databases and HTML
> don't know from Direction or Product, though, so it has to get serialized down to something for
> those.  For arbitrary objects, you basically have to write your own mechanism.  (I did.)  For enums,
> one comes built-in to make it more standardized: backed enums.

For what it's worth, the biggest downside to this decision is in
upgrading old/legacy projects to use enums. Most of the time, you want
to convert a const to an enum, and that also usually means it will be
a backed enum. Since there's no way to cast a backed enum to a
string/int, you have to instead add ->value (I really don't understand
the difference; casting would have been much more elegant); this
almost always results in lots of hidden runtime errors. At the last
couple of places, after seeing the damage the conversion could do,
doing this conversion was simply off-limits. Maybe by now, there is
some reliable tooling to handle this automatically... I haven't
looked. The point remains that it is a strange decision to use
->value but not allow (string) or (int) or allow even
implementing it yourself.

>
> >> I'm not sure if I'd support it myself at the moment
> > Noted, but I once again find myself needing to ask: why not? Were it up
> > to me, I'd say let's start right now! :)
>
> Mainly because I haven't thought it through to see what possible issues it could cause. 
> It may be safe, or there may be currently-not-obvious issues that would result.  That's the
> sort of thing we'd need to explore.
>
> For instance, how useful would it be, given that the casing for an enum should be CamelCase
> (per PER-CS), but the serialized string is most often snake_case, and otherwise lowerCamel?  We
> definitely cannot bake case folding magic into the behavior.  So is it even useful at that point?  I
> don't know.  Maybe.  That's what needs to be explored.

I don't see how casing of the backed value is relevant. If you want it
to be something different, then specify it in the class body. 9/10 of
the time, you just need to serialize the enum somewhere and the casing
doesn't matter. If it does matter, then specify the values manually.

>
> It's not something I'm planning to work on myself at this point, though if someone
> else wanted to dig into it I'm happy to help brainstorm with them..
>
> --Larry Garfield


Thread (21 messages)

« previous php.internals (#123409) next »