rfc:enum_allow_static_properties

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:enum_allow_static_properties [2021/05/18 00:20] tandrerfc:enum_allow_static_properties [2021/06/16 03:29] (current) tandre
Line 1: Line 1:
 ====== PHP RFC: Allow static properties in enums ====== ====== PHP RFC: Allow static properties in enums ======
-  * Version: 0.1+  * Version: 0.2
   * Date: 2021-05-17   * Date: 2021-05-17
   * Author: Tyson Andre, <tandre@php.net>   * Author: Tyson Andre, <tandre@php.net>
-  * Status: Under Discussion+  * Status: Declined
   * Implementation: https://github.com/php/php-src/pull/6997   * Implementation: https://github.com/php/php-src/pull/6997
   * First Published at: http://wiki.php.net/rfc/enum_allow_static_properties   * First Published at: http://wiki.php.net/rfc/enum_allow_static_properties
Line 27: Line 27:
   - [[https://en.wikipedia.org/wiki/Memoization|Memoization]] of expensive operations with no side effects (reading and parsing a large file from disk, cpu-intensive operations, service/db calls)   - [[https://en.wikipedia.org/wiki/Memoization|Memoization]] of expensive operations with no side effects (reading and parsing a large file from disk, cpu-intensive operations, service/db calls)
   - Keeping track of which enum case reflects the current state of a state machine or system   - Keeping track of which enum case reflects the current state of a state machine or system
 +
 +E.g. for [[https://en.wikipedia.org/wiki/Memoization|Memoization]], it may be useful to keep the result of expensive operations with no side effects in a static properties in the same module. Typically, php static properties are used where many other languages may have module functions and state in a file separate from a class definition (e.g. due to autoloading and coding standards requiring one class per file).
 +
 +<code php>
 +// https://en.wikipedia.org/wiki/Sprite_(computer_graphics)
 +enum Sprite {
 +    case FROG;
 +    case LOG;
 +    case GRASS;
 +    case WATER;
 +    // etc.
 +    
 +    /** @var array<string, MyModule\ImageData> */
 +    private static array $cache = [];
 +    
 +    public static function getImageData(SpriteArt $value): MyModule\ImageData {
 +        $key = $value->name;
 +        if (!isset(self::$cache[$key])) {
 +            self::$cache[$key] = self::loadImageData($value);
 +        }
 +        return self::$cache[$key];
 +    }
 +    
 +    // Called when is no longer used, the color scheme changed, etc.
 +    public static function clearImageData(SpriteArt $value): void {
 +        self::$cache = [];
 +    }
 +    
 +    // Slow operation: Read image data from disk and decode image data.
 +    public static function loadImageData(): void {
 +        // ...
 +    }
 +}
 +</code>
  
 For example, one way to represent fetching the current environment (of a known enumeration of environments) would be a static method on the environment enum itself. The environment instance is immutable, but the environment being loaded depends on a file. For example, one way to represent fetching the current environment (of a known enumeration of environments) would be a static method on the environment enum itself. The environment instance is immutable, but the environment being loaded depends on a file.
Line 70: Line 104:
  
 This is also useful because it allows enums to ''use'' traits that contain static properties, which was previously a fatal error. This is also useful because it allows enums to ''use'' traits that contain static properties, which was previously a fatal error.
 +
 +Projects may wish to enforce their own coding standards on how to appropriately use static properties in enums - e.g. I can imagine different projects may have different opinions, but having the functionality available to make use of would help their maintainers
 +
 +  * One project may forbid publicly visible static properties.
 +  * Another project may allow uses of static properties, but only if the enum's methods would be idempotent or appear to the callers to be free of side effects. (e.g. to permit memoization)
 +  * Another project may forbid static properties except when inherited from a trait that has other non-enum use cases.
 +
 +Quoting [[http://news.php.net/php.internals/71525|Rasmus]]:
 +
 +> PHP is and should remain:
 +> 1) a pragmatic web-focused language
 +> 2) a loosely typed language
 +> 3) a language which caters to the skill-levels and platforms of a wide range of users
  
 ==== This minimizes the backward compatibility impact of adding static properties to traits ==== ==== This minimizes the backward compatibility impact of adding static properties to traits ====
Line 112: Line 159:
  
 In some cases, enums may be associated with shared functionality that uses shared state, and static properties may be the most practical way for a developer/team to migrate it. In some cases, enums may be associated with shared functionality that uses shared state, and static properties may be the most practical way for a developer/team to migrate it.
 +
 +The following are potential use cases:
  
   - Migrating an application or library from other programming languages to a similar API in php, where files can have variables local to a module or if static variables are allowed. (For example, Java also allows static properties on enums whether or not they are final https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)   - Migrating an application or library from other programming languages to a similar API in php, where files can have variables local to a module or if static variables are allowed. (For example, Java also allows static properties on enums whether or not they are final https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
-  - Migrate code using PHP classes to PHP enums if those classes already depended on static properties in a way where refactoring was impractical+  - Migrating code using PHP classes to PHP enums (if those classes already depended on static properties in a way where refactoring was impractical).
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 131: Line 180:
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
 Instance properties continue to be forbidden on enums. Instance properties continue to be forbidden on enums.
 +
 +PHP enums were already able to have instance and static methods.
  
 ===== Discussion ===== ===== Discussion =====
Line 166: Line 217:
 Also a clarification, since it wasn't entirely clear in Tyson's original email: Static methods on Enums are already supported. They were included in the original Enum RFC. The change proposed here is just about static properties. Also a clarification, since it wasn't entirely clear in Tyson's original email: Static methods on Enums are already supported. They were included in the original Enum RFC. The change proposed here is just about static properties.
 </blockquote> </blockquote>
 +
 +Counterarguments include:
  
   - [[#this_is_better_than_alternative_ways_that_can_be_used_to_store_shared_state|This is better than alternative ways that can be used to store shared state]]   - [[#this_is_better_than_alternative_ways_that_can_be_used_to_store_shared_state|This is better than alternative ways that can be used to store shared state]]
Line 171: Line 224:
   - An application may start off by only using pure static methods to an enum. But it may later unexpectedly need to add shared state to new or existing methods after that design was already finalized, and continuing to implement the functionality in static methods on the enum instance would be the most consistent with previous design decisions.   - An application may start off by only using pure static methods to an enum. But it may later unexpectedly need to add shared state to new or existing methods after that design was already finalized, and continuing to implement the functionality in static methods on the enum instance would be the most consistent with previous design decisions.
  
-===== Proposed Voting Choices ===== +==== Would prefer that enums are collections of pure(side effect free) methods ==== 
-Yes/No, requiring a 2/3 majority+ 
 +https://externals.io/message/114494#114506 
 + 
 +<blockquote> 
 +Personally, I'd prefer to see enums as value objects only, adding static 
 +properties allow to implementation of statically conditional behaviour. 
 +IMO enums should consist only of pure functions. This is why I'd vote NO on 
 +this proposal. 
 + 
 +Cheers, 
 +Michał Marcin Brzuchalski 
 +</blockquote> 
 + 
 +  - Some operations that have no side effects and satisfying different definitions of pure (reading and parsing a large unchanging file from disk, cpu or memory-intensive operations, read-only service/db calls) may benefit from [[https://en.wikipedia.org/wiki/Memoization|Memoization]], which would rely on being able to save or read shared state 
 +  - Some end users may disagree with this philosophy, while others may be reluctantly forced into maintaining shared state due to unexpected feature requests or business logic reasons that weren't expected in the initial design. If functionality related to enums did end up using shared state, then [[#this_is_better_than_alternative_ways_that_can_be_used_to_store_shared_state|this is better than alternative ways that can be used to store shared state]]. 
 + 
 + 
 +===== Vote ===== 
 +This is a Yes/No vote, requiring a 2/3 majority
 + 
 +Voting started on June 1, 2021 and ends on June 15, 2021
  
 +<doodle title="Allow static properties in enums" auth="tandre" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 ===== References ===== ===== References =====
 https://externals.io/message/112626#113037 brought up the same suggestion. https://externals.io/message/112626#113037 brought up the same suggestion.
  
 [[enumerations|enums RFC]] [[enumerations|enums RFC]]
rfc/enum_allow_static_properties.1621297208.txt.gz · Last modified: 2021/05/18 00:20 by tandre