First, I'm pretty sure I agree now that enums should *not* be
`extend`-ed as regular classes, there's a fundamental difference as
you state - the extended enum is a fundamentally different THING as it
can hold different values - when an enum's sole purpose is to hold one
of the set of values.

That is to say - for most implementations that's the desired case.

I'll refer to the solution to the OP problem as ECS, Error Code System.

For ECS, the most elegant, but also the only, solution I can come up
with - is the kind of enum that you also suggest, a `base-enum`.
`abstract enum`?

Let me try again to describe the problem that I came here with that is
unsolvable by union types:

1. ECS is a *generic* component. I want to plug it into any working
system (like an existing cms).
2. Invoking it must provide a unique ErrorCode. The existing cms has
to create an enum that will be accepted as `type: ErrorCode`. It
cannot edit the existing ErrorCode as it is part of ECS and not the
cms.
3. There is NO special handling for the custom ErrorCode's that the
users of ECS create. We are just using the enums inferred value.

I will keep processing this situation further, but for now it seems to me like

1. Extending enums is fundamentally flawed.
2. Basing enums off of other enums has valid usage scenarios.

In that case, and, again, this needs way more thought to it, it's not
such a "generic way forward" that seemed to me at first and might only
provide marginal value at the cost of type complexity and that is most
probably, unfortunately, not worth it...

(unless `abstract enum` might make sense, but my brain needs some time
off of this problem for now)

Thank you for such a thought out discussion, everyone!


On Wed, 29 Mar 2023 at 16:56, Rowan Tommins <rowan.coll...@gmail.com> wrote:
>
> On Wed, 29 Mar 2023 at 14:22, Rokas Šleinius <rave...@gmail.com> wrote:
>
> > Ok so I am trying to find the argumentation here:
> >
> > >This is by design.
> > >The point of enums is to be limiting.
> >
> > This is clearly an assumption. That statement is not in the docs or
> > RFC, nor such an oversimplification makes logical sense to me, but
> > maybe you have a source to back it up..?
> >
>
>
> From a theory point of view, *any* type definition is about limiting
> allowed values. The difference between "mixed" and "integer" is that
> "mixed" allows both 'Hello' and 42, but "integer" does not - it defines a
> tighter limit.
>
> In the same way, saying "I accept an error code" means "I accept an error
> code *and nothing else*" - the definition of what is and what isn't an
> "error code" is deliberately a *limit* on the values that you accept.
>
>
>
> >
> > >Re: problem in the OP
> > >You are approaching the design of this in a fundamentally wrong way.
> >
> > The described problem is dealing with error *codes* not *types*
>
>
>
> An enum is a type, so that's why George was talking about types. He was
> making the same point, in different words, as I did: the relationship
> between types implied by the keyword "extends" is not the relationship you
> want in this case.
>
>
>
> > The set in question is *finite*, as you say of course, but much larger
> > and different in principle than in the solution you are proposing.
> > Problem in OP is looking for a way for end users to keep adding new
> > domains to the error codes passed to the parent system to be handled.
> >
>
>
> This is the key point - if you pass an error code that didn't previously
> exist, the existing system *won't* be able to handle it.
>
> That's why enums are inherently restrictive: the system wants to be able to
> say "this is the list of error codes I understand, don't give me anything
> else".
>
> If you have a system that accepts the new codes as well as the old ones,
> you can use a union type declaration as George says:
>
> enum AdditionalErrorCode {
>     case Code_456;
> }
>
> class ExtendedErrorHandler extends StandardErrorHandler {
>     public function handle(StandardErrorCode|AdditionalErrorCode $code) {
>          switch ( $code ) {
>              case AdditionalErrorCode::Code_456:
>                 // handling for new code goes here
>              break;
>              default:
>                  // assert($code instanceof StandardErrorCode);
>                  parent::handle($code);
>              break;
>         }
>     }
> }
>
> Regards,
> --
> Rowan Tommins
> [IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to