Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

RFC draft

SamNrique edited this page · 4 revisions
Clone this wiki locally

Enum - alternative proposal

Introduction

One year ago, there was a proposal to provide enum concept for php language (previous rfc here).

The proposal was not yet approved, so this is another approach for enums

At the end of this RFC there are other sub-proposals

Abstract

enum is a popular keyword, used in several languages.

The current RFC proposes to write things like this:

enum eDirections {
    left,
    right,
    top,
    bottom
}

foreach (eDirections::to_array() as $key => $value) {
    if(is_traversable($value)){
        echo "You can go to the ", $key, "<br />\n";
    }
}

Initial ideas are:

  • An enum value should be an integer
  • An enum type should have a name
  • An enum type should be namespace-able
  • An enum value have always an associated name, but it's not what matter most

Declaration

Syntax:

enum EnumTypeName { valueName [ = intValue ] [, valueName [ = intValue ] ] … }

  • EnumTypeName is the name of the newly defined enum type
  • valueName is the name of a new value
  • intValue is the new defined value

Value determination

  • If a value is not provided explicitly, it is the previous value +1
  • If there is no previous value defined in this enum declaration, the value is 1
  • If an explicitly defined value is less than any other value previously defined in the current enum declaration, this is a Parse Error

Example:

enum myEnum {
    foo,
    bar = 5
}

Enum values

Enum values are integer.

You can access to enum values like class constants:

EnumTypeName::valueName

Example:

var_dump(myEnum::foo); // => int(1)

The enum type

  • The enum declaration create a new type, like a class or an interface declaration
  • An enum type is not a class.
  • An enum type is not an interface.
  • An enum type is not a trait.
  • The enum type should not be extended, implemented, used (as Traits) nor instantiated
  • The enum declaration could be done in a namespace, like a class

built-in global functions

enum_exists

This is the counterpart of interface_exists and class_exists

Prototype : bool enum_exists(string name)

Return true if name is the fully qualified name of a declared enum type.

get_defined_enums

This is the counterpart of get_defined_interfaces and get_defined_classes

Prototype : array get_defined_enums()

Return a list of all the declared enum types.

enum static methods

length

This method should be used to know how many values are defined in an enum type

Prototype : int EnumTypeName::length()

Example :

var_dump(myEnum::length()); // => int(2)

contains

This method should be used to know if a value is defined in an enum type

Prototype : bool EnumTypeName::contains(int value)

Example :

var_dump(myEnum::contains(5)); // => bool(true)

name

This method should be used to know the name of an existing value

Prototype : string EnumTypeName::name(int value)

Example :

var_dump(myEnum::name(5)); // => string(3) "bar" var_dump(myEnum::name(3)); // => NULL

names

This method should be used to get the names of all defined values

Prototype : array EnumTypeName::names()

Example :

var_dump(myEnum::names()); // => array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" }

values

This method should be used to get all defined values

Prototype : array EnumTypeName::values()

Example :

var_dump(myEnum::values()); // => array(2) { [0]=> int(1) [1]=> int(5) }

to_array

This method should be used to get all defined values and their names

Prototype : array EnumTypeName::to_array()

Example :

var_dump(myEnum::to_array()); // => array(2) { ["foo"]=> int(1) ["bar"]=> int(5) }

Implementation

You can find here an implementation proposal. I've tried to make it cleany and less execution time consumer.

This is my first PHP core hack, so:

  • please check my work (for memory leaks, deprecated usage, etc...)
  • Tell me when I missed/failed something
  • Be kind with me ^^

Sub-proposal 1 : Type checking

Definition

This sub-proposal is to use function argument type checking the same way it does for classes and instances.

Usage Example:

function myFunction(myEnum $arg){
    echo $arg;
}

myFunction(myEnum::foo);  // => 1
myFunction(1);            // => 1
myFunction("1");          // => 1
myFunction(4);            // => Catchable fatal error: Argument 1 passed to myFunction() must be a value of enum myEnum, int given

Implementation:

You can find this additional implementation here

Sub-proposal 2 : count override

Definition

This sub-proposal seeks to provide a syntaxic sugar to get length of an enum type

Usage Example:

count(myEnum)  // => 2, same as myEnum::length()

Drawback

  • count is a really often used function, and any slowdown could have large effect
  • There will be two ways to get the length of an enum type

Implementation

No implementation yet

Sub-proposal 3 : as override

Definition

This sub-proposal seeks to provide a syntaxic sugar to iterate of values of an enum type

Usage Example:

foreach(myEnum as $key => $value)  // same as foreach(myEnum::to_array() as $key => $value)

Drawback

  • as is a really often used keyword, and any slowdown could have large effect
  • a little bit less precise as to_array(), values() and names

Implementation

No implementation yet

Sub-proposal 4 : instanceof override

Definition

This sub-proposal seeks to provide a syntaxic sugar to check if a variable exists in an enum type

Usage Example:

var_dump($value instanceof myEnum);  // same as var_dump(myEnum::contains($value);

Drawback

  • instanceof is a really often used keyword, and any slowdown could have large effect
  • There will be two ways to check if a variable exists in an enum type

Implementation

No implementation yet

Something went wrong with that request. Please try again.