rfc:readonly_and_immutable_properties

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
rfc:readonly_and_immutable_properties [2020/06/21 12:47] – some further fixes andreromrfc:readonly_and_immutable_properties [2020/06/21 18:47] (current) – formating andrerom
Line 14: Line 14:
 **This is a early draft, currently looking for feedback on direction on what would make most sense to propose, especially if there is any point in even exploring using Attributes for the features covered here or not.** **This is a early draft, currently looking for feedback on direction on what would make most sense to propose, especially if there is any point in even exploring using Attributes for the features covered here or not.**
  
-With the introduction of typed properties in PHP 7.4, properties have become far more powerful. However it is currently not possible to specify disconnected write vs read visibility for properties without having to resort to magic methods (getters and setters), for immutable semantic it's even more cumbersome. This requires unnecessary boilerplate, makes usage less ergonomic and hurts performance.+With the introduction of typed properties in PHP 7.4, properties have become far more powerful. However it is currently not possible to specify disconnected write vs read visibility for properties, such as readonly, without having to resort to magic methods (getters and setters). For immutable semantic it's even more cumbersome. This requires unnecessary boilerplate, makes usage less ergonomic and hurts performance.
  
 This RFC resolves this issue by proposing a few options: This RFC resolves this issue by proposing a few options:
Line 22: Line 22:
     - immutable keyword for write access, on property and class (implicit all properties)     - immutable keyword for write access, on property and class (implicit all properties)
   - Attribute approach:   - Attribute approach:
-    - Readonly attribute for properties, if #1.1 is accepted this is merely syntax sugar that adds possibility to set readonly on classes (implicit all properties)+    - Readonly attribute for properties, if #1.1/1.2 is accepted this is merely syntax sugar. 
-    - Immutable attribute for properties, if #1.is accepted this is merely syntax sugar that adds possibility to set immutability on classes (implicit all properties). +    - Immutable attribute for properties, if #1.is accepted this is merely syntax sugar
- +
- +
-//One of the options here are intended to be ruled out during early discussions//+
  
  
Line 111: Line 108:
 ==== Readonly ==== ==== Readonly ====
  
-This RFC aligns with [[rfc:readonly_properties|Readonly properties]] (2014, Withdrawn), however also proposing a more granular way of defining readonly access rules.+This RFC aligns with [[rfc:readonly_properties|Readonly properties]] (2014, Withdrawn).
  
  
Line 117: Line 114:
  
  
-This RFC aligns with [[rfc:immutability|Immutability]] (2018, Stale), however also proposing a more granular way of defining immutable access rules.+This RFC aligns with [[rfc:immutability|Immutability]] (2018, Stale).
  
 This RFC does __not__ align with the semantics of the recent [[rfc:write_once_properties|Write once properties]] (2020, Declined), which is targeting a different problem. This RFC does __not__ align with the semantics of the recent [[rfc:write_once_properties|Write once properties]] (2020, Declined), which is targeting a different problem.
Line 125: Line 122:
  
  
-This RFC does not try to solve as wider use case as the different iterations of [[rfc:propertygetsetsyntax-v1.2|Property Accessors Syntax]].+This RFC does not try to solve as wide use case as the different iterations of [[rfc:propertygetsetsyntax-v1.2|Property Accessors Syntax]] does.
  
-It's of this author's opinion that property type hinting and accessors where the two main obstacles to previous attempts at adding readonly semantics to PHP properties back in 2012-2014. And while readonly is rather hard to do in a clean way in PHP today, most other use cases offered by Accessors can be accomplished by plain PHP methods. Finally, Accessors overcomplicates readonly use case, and does not solve the needs for immutable property semantics. +However: 
- +- Accessors overcomplicates readonly, and does not offer solutions to immutability 
-Thus the author of this RFC believes what is proposed here should be done before any proposal for Accessors is re-consideredas anything here can be made syntax sugar for Accessors, if it ever gets accepted.+- There seems to be a higher need in the community for readonly and immutable semantics 
 +- Everything Accessors offers beyond disconnected read and write visibility for properties, can easily be done with plain methods. The same is not true for readonly and immutable semantics as shown in the introduction.
  
  
Line 156: Line 154:
     public:protected string $name;     public:protected string $name;
          
-    // Property is writeonly in public and protected scope+    // Property is write-only in public and protected scope
     private:public string $newName;     private:public string $newName;
  
Line 171: Line 169:
 == Reflection == == Reflection ==
  
-When using reflection, methods such as "ReflectionProperty::setAccessible()will work as before, it will implicit set visibility for both read and write.+When using reflection, methods such as ''ReflectionProperty::setAccessible()'' will work as before, it will implicit set visibility for both read and write.
  
 However with this proposal the following existing methods will represent read visibility for cases where it differs: However with this proposal the following existing methods will represent read visibility for cases where it differs:
-- ReflectionProperty::isPrivate +''ReflectionProperty::isPrivate()'' 
-- ReflectionProperty::isProtected +''ReflectionProperty::isProtected()'' 
-- ReflectionProperty::isPublic+''ReflectionProperty::isPublic()''
  
 And for checking separate write visibility the following methods may be used: And for checking separate write visibility the following methods may be used:
-- ReflectionProperty::isWritePrivate — Checks if property is writable in private +''ReflectionProperty::isWritePrivate'' — Checks if property is writable in private 
-- ReflectionProperty::isWriteProtected — Checks if property is writable in protected +''ReflectionProperty::isWriteProtected'' — Checks if property is writable in protected 
-- ReflectionProperty::isWritePublic — Checks if property is writable in public+''ReflectionProperty::isWritePublic'' — Checks if property is writable in public
  
  
-"Reflection::getModifiers()and "Reflection::getModifierNames()will need adaption too, and proposal is to adapt it so "getModifierNames()continues to return the visibility as specified, meaning it may now return for instance "public:protectedas one of the strings returned.+''Reflection::getModifiers()'' and ''Reflection::getModifierNames()'' will need adaption too, and proposal is to adapt it so ''getModifierNames()'' continues to return the visibility as specified, meaning it may now return for instance ''public:protected'' as one of the strings returned.
  
 //TODO: Expand this with modifier ints representing all variations and their names// //TODO: Expand this with modifier ints representing all variations and their names//
Line 238: Line 236:
 == Reflection == == Reflection ==
  
-When using reflection, methods such as "ReflectionProperty::setAccessible()will work as before, it will implicit disable immutable flag.+When using reflection, methods such as ''ReflectionProperty::setAccessible()'' will work as before, it will implicit disable readonly flag.
  
-Furthermore the following method is proposed added to be able to detect immutable properties: +Furthermore the following method is proposed added to be able to detect readonly properties: 
-- ReflectionProperty::isImmutable+''ReflectionProperty::isReadonly()''
  
  
-"Reflection::getModifiers()and "Reflection::getModifierNames()will need adaption too to add int and keywords for "immutable".+''Reflection::getModifiers()'' and ''Reflection::getModifierNames()'' will need adaption too to add int and keywords for "readonly".
  
-//TODO: Expand this with specific modifier int for "immutable"//+//TODO: Expand this with specific modifier int for "readonly"//
  
  
Line 295: Line 293:
 == Reflection == == Reflection ==
  
-When using reflection, methods such as "ReflectionProperty::setAccessible()will work as before, it will implicit disable immutable flag.+When using reflection, methods such as ''ReflectionProperty::setAccessible()'' will work as before, it will implicit disable immutable flag.
  
 Furthermore the following method is proposed added to be able to detect immutable properties: Furthermore the following method is proposed added to be able to detect immutable properties:
-- ReflectionProperty::isImmutable+''ReflectionProperty::isImmutable()''
  
  
Line 307: Line 305:
 ==== 2. Attributes ==== ==== 2. Attributes ====
  
-With the recently accepted [[rfc:attributes_v2|Attribute v2 RFC]], another option here, or an supplemental one , would be to use attributes for introducing Readonly and Immutable semantics. Similar to how Rust does with its [[https://docs.rs/readonly/0.1.6/readonly/|readonly create]].+With the recently accepted [[rfc:attributes_v2|Attribute v2 RFC]], another option here, or supplemental one, would be to use attributes for introducing Readonly and Immutable semantics. Similar to how Rust does with its [[https://docs.rs/readonly/0.1.6/readonly/|readonly create]].
  
 However the Attribute RFC does not allow for what is being drafted here, so this would need suggesting a way for userland classes to tell parser / compiler to enhance language features. However the Attribute RFC does not allow for what is being drafted here, so this would need suggesting a way for userland classes to tell parser / compiler to enhance language features.
Line 409: Line 407:
 == Reflection == == Reflection ==
  
-//TODO: show example on reading /setting attribute via reflection, and how this relates to "ReflectionProperty::setAccessible()".//+//TODO: show example on reading /setting attribute via reflection, and how this relates to ''ReflectionProperty::setAccessible()''.//
  
  
Line 417: Line 415:
 Code that expects to be able to make properties writeable via reflection will have to adapt for new code taking advantage of this. Code that expects to be able to make properties writeable via reflection will have to adapt for new code taking advantage of this.
  
-While ReflectionProperty::setAccessible() will still work like before, checks using isProtected() or isPrivate() won't detect if class has other visibility for write (proposal #1), or take into account specific attributes affecting write (assuming proposal #1 is voted down and Readonly and Immutable becomes own attribute logic instead of merely syntax sugar for #1)+While ''ReflectionProperty::setAccessible()'' will still work like before, checks using ''isProtected()'' or ''isPrivate()'' won't detect if class has other visibility for write (proposal #1), or take into account specific attributes affecting write (assuming proposal #1 is voted down and Readonly and Immutable becomes own attribute logic instead of merely syntax sugar for #1.x)
  
  
Line 430: Line 428:
 ===== Performance ===== ===== Performance =====
  
-//Performance tests will need to be done once there is implementation of this. Then overhead on properties, as well as measuring benefit over using magic methods.//+//Performance tests will need to be done once there is an implementation of this. Then overhead on properties, as well as measuring benefit over using magic methods.//
  
 ===== Vote ===== ===== Vote =====
  
 As this is a language change, a 2/3 majority is required. As this is a language change, a 2/3 majority is required.
-//RFC is in draft, and will undergo discussion phase before it is put for a vote.// 
  
 ===== References ===== ===== References =====
Line 441: Line 438:
  
   * [[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#readonly-fields|C# readonly fields]], semantically similar to what is proposed as "immutable" here.   * [[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#readonly-fields|C# readonly fields]], semantically similar to what is proposed as "immutable" here.
 +  * [[https://docs.rs/readonly/0.1.6/readonly/|Rust readonly create]]
  
  
rfc/readonly_and_immutable_properties.1592743650.txt.gz · Last modified: 2020/06/21 12:47 by andrerom