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
Last revisionBoth sides next revision
rfc:readonly_and_immutable_properties [2020/06/21 12:19] – first draft read to get feedback on deciding direction andreromrfc:readonly_and_immutable_properties [2020/06/21 12:47] – some further fixes andrerom
Line 19: Line 19:
   - Language approach:   - Language approach:
     - Change to make it possibility to specify write visibility disconnected from read.     - Change to make it possibility to specify write visibility disconnected from read.
-    - Immutable keyword for immutable semantics on write access+    - readonly 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 is accepted this is merely syntax sugar that adds possibility to set readonly on classes (implicit all properties).
Line 25: Line 26:
  
  
-//Unless discussions phase points to clear preference within php internals and broader community, these four proposals will be offered as separate votes. Technically all 4 options can be accepted, however downside is there will be more than one way of doing things. So maybe a discussion on where Attributes fits into the language in the future is needed as well.//+//One of the options here are intended to be ruled out during early discussions//
  
  
Line 110: Line 111:
 ==== Readonly ==== ==== Readonly ====
  
-This RFC differs from [[rfc:readonly_properties|Readonly properties]] (2014, withdrawnby instead using the recently accepted Attribute language feature for annotating Readonly properties. As done in Rustand in user land annotations in many PHP frameworks.+This RFC aligns with [[rfc:readonly_properties|Readonly properties]] (2014, Withdrawn), however also proposing a more granular way of defining readonly access rules.
  
  
Line 116: Line 117:
  
  
-This RFC differs from[[rfc:immutability|Immutability]] (2018, staleby instead using the recently accepted Attribute language feature for annotating Immutable properties. Aligning with Readonly proposal within this RFC.+This RFC aligns with [[rfc:immutability|Immutability]] (2018, Stale), however also proposing a more granular way of defining immutable access rules.
  
-This RFC does __not__ align with the semantics of the recent [[rfc:write_once_properties|Write once properties]], 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 133: Line 134:
 ===== Proposal ===== ===== Proposal =====
  
-==== 1.1 Language ability to set property visibility for write access ====+==== Common semantics ==== 
 + 
 +== References == 
 + 
 +Attempting to pass a property value outside of allowed writable scope as a reference, results in an error. 
 + 
 + 
 +==== 1. Language Approach ==== 
 + 
 + 
 +=== 1.1 Language ability to set property visibility separately for write access ===
  
 This proposal adds support for enforced write visibility checks for declared properties. The following example illustrates the basic syntax: This proposal adds support for enforced write visibility checks for declared properties. The following example illustrates the basic syntax:
Line 155: Line 166:
 </code> </code>
  
-The format is "<read_visibility>:<write_visibility>", and if you omit the last visibility value you will like before implicit set both read and write visibility at once _(unless other future keywords or attributes states otherwise).  +The format is "<read_visibility>:<write_visibility>", and if you omit the last visibility value you will like before implicit set both read and write visibility at once _(unless other future keywords or attributes states otherwise).
- +
- +
-== References == +
- +
-Attempting to pass a property value outside of allowed scope as reference, is an error. +
  
  
Line 183: Line 188:
 //TODO: Expand this with modifier ints representing all variations and their names// //TODO: Expand this with modifier ints representing all variations and their names//
  
 +=== 1.2 readonly keyword ===
 +
 +This proposal adds support for runtime-enforced readonly write visibility for declared properties. The following example illustrates the basic syntax:
 +
 +<code php>
 +class User {
 +    // Property is readonly, and can only be written to in protected scope
 +    public readonly int $id;
 +    
 +    // Property is readonly, and can only be written to in private scope
 +    protected readonly string $name;
 +
 +    // [assuming 1.1 is accepted] Invalid declaration (visibility is already stating property is readonly)
 +    public:private readonly string $email;
 +
 +    public function __construct(int $id, string $name) {
 +        $this->id = $id;
 +        $this->name = $name;
 +    }
 +}
 +</code>
 +
 +Keyword can also be set on class level, implicit setting it on all fields unless they have their own immutable attribute:
 +
 +<code php>
 +readonly class User {
 +    // Property is readonly, and can only be written to in protected scope
 +    public int $id;
 +    
 +    // Property is readonly, and can only be written to in private scope
 +    protected string $name;
 +
 +    // [assuming 1.1 is accepted] Invalid declaration (visibility is already stating property is readonly)
 +    public:private string $email;
 +
 +    public function __construct(int $id, string $name) {
 +        $this->id = $id;
 +        $this->name = $name;
 +    }
 +}
 +</code>
 +
 +
 +== Readonly semantics ==
 +
 +An readonly property may only be written to in scope lower than what is define as its read+write visibility, so if visibility is public, it may only be written to in protected scope.
 +
 +
 +== Reflection ==
 +
 +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:
 +- ReflectionProperty::isImmutable
 +
 +
 +"Reflection::getModifiers()" and "Reflection::getModifierNames()" will need adaption too to add int and keywords for "immutable".
 +
 +//TODO: Expand this with specific modifier int for "immutable"//
  
  
-=== 1.2 Language ability to set immutable property visibility for write access ===+=== 1.immutable keyword ===
  
 This proposal adds support for runtime-enforced immutable write visibility for declared properties. The following example illustrates the basic syntax: This proposal adds support for runtime-enforced immutable write visibility for declared properties. The following example illustrates the basic syntax:
Line 192: Line 256:
 class User { class User {
     // Property is immutable, can only be written to in __construct in protected scope     // Property is immutable, can only be written to in __construct in protected scope
-    public immutable string $id;+    public immutable int $id;
  
     // [assuming 1.1 is accepted] Property is immutable, can only be written to in __construct in private scope     // [assuming 1.1 is accepted] Property is immutable, can only be written to in __construct in private scope
Line 203: Line 267:
 } }
 </code> </code>
 +
 +Keyword can also be set on class level, implicit setting it on all fields unless they have their own readonly attribute:
 +
 +<code php>
 +immutable class User {
 +    // Property is immutable, can only be written to in during construction in protected scope
 +    public int $id;
 +    
 +    // Property is immutable, can only be written to during construction in private scope
 +    protected string $email;
 +
 +    public function __construct(int $id, string $email) {
 +        $this->id = $id;
 +        $this->email = $email;
 +    }
 +}
 +</code> 
  
  
 == Immutable semantics == == Immutable semantics ==
  
-An immutable property may only be written to in __construct() and in other methods involved in object creation (__set_state__unserialize, __wakeup, and unserialize), besides that it is allowed to be unset in __destruct()+An immutable property may only be written to in construct and in other methods involved in object creation (set_stateunserialize, and wakeup), besides that it is allowed to be unset in destruct
  
 Unless otherwise specified in visibility, the write/unset access is available within protected scope. Unless otherwise specified in visibility, the write/unset access is available within protected scope.
Line 233: Line 314:
  
  
-==== 2.1 Readonly attribute ====+=== 2.1 Readonly attribute ===
  
  
Line 243: Line 324:
 class User { class User {
     <<Readonly>>     <<Readonly>>
-    public string $id;+    public int $id;
  
     // This property is not readonly     // This property is not readonly
Line 263: Line 344:
 class User { class User {
     // This property is readable in public scope and writeable in protected     // This property is readable in public scope and writeable in protected
-    public string $id;+    public int $id;
          
     // This property is readable in protected scope and writeable in private     // This property is readable in protected scope and writeable in private
Line 275: Line 356:
 </code>  </code> 
  
 +//For readonly semantics see proposal 1.2//
  
-== Readonly semantics == 
  
-An readonly property may only be written to in scope lower than what is define as its read+write visibility, so if visibility is public, it may only be written to in protected scope. +== Reflection ==
  
 +//TODO: show example on reading /setting attribute via reflection, and how this relates to "ReflectionProperty::setAccessible()".//
  
-==== 2.2. Immutable attribute ====+ 
 + 
 +=== 2.2. Immutable attribute ===
  
 This proposal adds a compiler attribute which implies a runtime-enforced immutable write visibility checks for declared properties. The following example illustrates the basic syntax: This proposal adds a compiler attribute which implies a runtime-enforced immutable write visibility checks for declared properties. The following example illustrates the basic syntax:
Line 290: Line 374:
 class User { class User {
     <<Immutable>>     <<Immutable>>
-    public string $id;+    public int $id;
  
     public string $email;     public string $email;
Line 310: Line 394:
 <<Immutable>> <<Immutable>>
 class User { class User {
-    public string $id;+    public int $id;
     public string $email;     public string $email;
  
Line 321: Line 405:
  
  
-//For immutable semantics see proposal 1.2, when setting the attribute on semantics will be //+//For immutable semantics see proposal 1.3//
  
 == Reflection == == Reflection ==
  
- +//TODO: show example on reading /setting attribute via reflection, and how this relates to "ReflectionProperty::setAccessible()".//
-==== 3.0 Class only attribute ==== +
- +
-One third option here, is that if 1.x proposals are accepted, and the proposed attributes in 2.x are accepted but only for being specified on class level, where it adds the capability to affect all properties. +
- +
-Alternative would be to propose class level keyword for "readonly" and "immutable". +
  
  
rfc/readonly_and_immutable_properties.txt · Last modified: 2020/06/21 18:47 by andrerom