Re: Let's discuss enums!
| From: | Bob Weinand | Date: | Thu, 17 Sep 2015 23:16:23 +0000 |
| Subject: | Re: Let's discuss enums! | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-88295@lists.php.net to get a copy of this message | ||
> Am 18.09.2015 um 01:06 schrieb Rowan Collins <rowan.collins@gmail.com>:
>
> Hi All,
>
> This has come up in passing a few times recently, but I'm not sure there's ever been
> a dedicated discussion of it: would it be useful for PHP to have a built-in Enumeration type, and if
> so, how should it look?
>
> Many other languages have enum types, with varying functionality. The central concept is always
> that there's some declared type with a bunch of named constants, but beyond that there's a
> lot of variability: for starters, is it a type of object, a special way of naming integers, or an
> uncomparable type more like booleans and nulls?
>
>
> Here are my thoughts on what I'd like from a PHP enum - I'm not using
> "should" in a particularly strong sense, it's just a way of framing the points of
> discussion:
>
> 1) enums should act like values, not mutable objects; an array-style copy-on-write behaviour
> would be possible, but it feels wrong to me to store any state in an enum variable, so just plain
> immutable would be my preference
>
> 2) the members of an enum should have a name which is accesible as a string, e.g.
> Weekdays::SUNDAY->getName() == 'SUNDAY'
>
> 3) there should be no accessible "value" for a member; the value of Weekdays::SUNDAY
> is simply Weekdays::SUNDAY, not 0 or 7 or 'SUNDAY' (I'm thinking that internally,
> each member would be represented as an object pointer, so there's no real benefit to forcing
> people to number everything like some languages do)
>
> 4) each enum member should be considered a singleton, in the sense that you can't
> construct or destroy one, only reference them; all possible instances would be created as soon as
> the enum was defined
>
> 5) following from (3) and (4), an enum value should compare equal only to itself, unlike in C#
> for instance, where it would be comparable to an integer based on its numeric value; similarly it
> shouldn't be possible to cast to or from an enum
>
> 6) an enum should be able to have additional fields; these would be initialised in the
> enum's definition; this is inspired by Java and Python's ability to pass parameters to the
> "constructor" of the enum, but it feels weird to me for any logic to happen in that
> constructor other than simple assignments, so I'm thinking of a simpler syntax and
> implementation. It also simplifies immutability if no userland code ever writes to the properties.
> There may be an important use case for constructor logic I'm missing though?
>
> 7) an enum should have default static methods for accessing all the members of the enum as an
> associative array
>
> 8) enums should be a first-class type, is_object(Weekdays::SUNDAY) should return false, for
> instance; maybe Weekdays::SUNDAY instanceof Weekdays should return true though
>
> 9) additional static and instance methods should be definable, bearing in mind the immutability
> constraints already discussed
>
>
> Given the above, I think we might end up with something like this:
>
> enum Weekdays {
> member MONDAY; // if there are no fields to initalise, the member just needs its name
> declaring
> member TUESDAY ( 2, 'Chewsdae' ); // positional arguments for populating fields in
> the order they are defined; a bit like Java, but without the constructor
> member WEDNESDAY { $dayNumber = 3, $sillyName = 'Wed Nose Day' }; // or maybe a
> named-parameter syntax to make things clearer
> member THURSDAY, FRIDAY, SATURDAY, SUNDAY; // don't force people to write each entry on
> its own line; maybe even the "member" keyword is too much?
>
> public $dayNumber, $sillyName; // fields initialised for each member
>
> public static function getWeekend() {
> return [ self::SATURDAY, self::SUNDAY ];
> }
>
> public function getZeroIndexedDayNumber() {
> return $this->dayNumber - 1;
> }
> }
>
> $today = Weekdays::THURSDAY;
> foreach ( Weekdays::getMembers() as $day_name => $day ) {
> echo $day->dayNumber;
> if ( $day == $today ) {
> echo "Today!";
> } else {
> echo $day_name; // equivalently: echo $day->getName();
> }
> }
>
> // Do we need a static method to access a member by name, or is this good enough?
> $favourite_day = Weekdays::getMembers()[ $_GET['fav_day'] ];
>
> So, what are anyone's thoughts? Am I rambling on too much as usual? ;)
>
> Regards,
>
> --
> Rowan Collins
> [IMSoP]
I like enums in general, but I'd like to note that there's already a RFC in draft by Levi:
https://wiki.php.net/rfc/enum <https://wiki.php.net/rfc/enum>
As far as I know, the RFC is already fairly final and just lacks an implementation.
So, I'd consider bikeshedding an actual RFC first.
Bob