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]


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

Reply via email to