Re: [RFC] Enumerations
| From: | Larry Garfield | Date: | Tue, 08 Dec 2020 17:40:48 +0000 |
| Subject: | Re: [RFC] Enumerations | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112469@lists.php.net to get a copy of this message | ||
On Sat, Dec 5, 2020, at 2:26 PM, Larry Garfield wrote:
> On Fri, Dec 4, 2020, at 5:24 PM, Larry Garfield wrote:
> > Greetings, denizens of Internals!
> >
> > Ilija Tovilo and I have been working for the last few months on adding
> > support for enumerations and algebraic data types to PHP. This is a
> > not-small task, so we've broken it up into several stages. The first
> > stage, unit enumerations, are just about ready for public review and
> > discussion.
> >
> > The overarching plan (for context, NOT the thing to comment on right
> > now) is here: https://wiki.php.net/rfc/adts
> >
> > The first step, for unit enumerations, is here:
> >
> > https://wiki.php.net/rfc/enumerations
> >
> > There's still a few bits we're sorting out and the implementation is
> > mostly done, but not 100% complete. Still, it's far enough along to
> > start a discussion on and get broader feedback on the outstanding nits.
> >
> > I should note that while the design has been collaborative, credit for
> > the implementation goes entirely to Ilija. Blame for any typos in the
> > RFC itself go entirely to me.
> >
> > *dons flame-retardant suit*
> >
> > --
> > Larry Garfield
> > larry@garfieldtech.com
>
> Thank you everyone for the feedback so far! I've updated the RFC with
> a few changes, based on discussion here and elsewhere:
>
> * Clarified that "enums behave like objects unless otherwise
> specified." That should clarify a lot of edge case questions. (Which
> is specifically one of the reasons to build off of objects. We can
> inherit answers to most edge cases.)
> * Primitive-backed Cases have been renamed to Scalar Enums, because
> "Primitive-backed" is just too clumsy to say or write all the time.
> * There's now formal internal interfaces defined for Enum, UnitEnum,
> and ScalarEnum to define the methods mentioned. These serve as both
> documentation and to allow user-space code to tell when a value it's
> dealing with is an enum, and a particular type of enum. (And therefore
> what enum methods are available.)
> * Added a value() method to ScalarEnum, to make it easier to get at the
> scalar equivalent arbitrarily.
> * Fixed a bunch of typos.
> * Updated the reflection section to have getType() return a
> ReflectionType rather than a bare string.
>
> (The patch will be updated for the above shortly as Ilija's time allows.)
Another update:
Based on feedback here, and after further discussion with Ilija and NIkita, we're going to try
a different tack on some implementation details. Specifically:
* We're going to shift Enums to be a single class with a bunch of secret properties inside to
hold the different case object instances, rather than a class per case. That should make the
overall memory usage lower, especially for enums with a large number of cases. As an unfortunate
side effect, this will preclude per-case methods, at least for now. :-(
* The ReflectionCase class will naturally go away at that point.
* For serialization, we'll introduce a new serialization marker, enum, which will make it
feasible too round-trip an enum while maintaining singleton-ness. More specifically, the
deserialize routine would essentially become $type::from($value), where $type and $value are pulled
from the serialized version.
I was also wrong in one of my earlier statements; as currently implemented, enum cases are
implemented as class constants that reference an object. (Something the engine is allowed to do
even if user code cannot.) That means they *do* work as parameter defaults and can be assigned as a
default value of an object property or constant. Huzzah!
Because it's the holidays these changes won't be immediate, but expect us to come back in
a few weeks with the next draft.
Thank you everyone for your interest!
--Larry Garfield