On Wed, May 22, 2024 at 4:13 AM Larry Garfield <la...@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

Reply via email to