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 internals+get-123409@lists.php.net to get a copy of this message
On Wed, May 22, 2024 at 4:13 AM Larry Garfield <larry@garfieldtech.com> 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

« previous php.internals (#123409) next »