rfc:readonly_and_immutable_properties
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:readonly_and_immutable_properties [2020/06/21 12:19] – first draft read to get feedback on deciding direction andrerom | rfc: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, | + | 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, |
This RFC resolves this issue by proposing a few options: | This RFC resolves this issue by proposing a few options: | ||
- 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 | + | - readonly |
+ | - 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.2 is accepted this is merely syntax sugar that adds possibility to set immutability on classes (implicit all properties). | + | - Immutable attribute for properties, if #1.3 is accepted this is merely syntax sugar |
- | + | ||
- | + | ||
- | //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.// | + | |
Line 110: | Line 108: | ||
==== Readonly ==== | ==== Readonly ==== | ||
- | This RFC differs from [[rfc: | + | This RFC aligns with [[rfc: |
Line 116: | Line 114: | ||
- | This RFC differs from[[rfc: | + | This RFC aligns with [[rfc: |
- | This RFC does __not__ align with the semantics of the recent [[rfc: | + | This RFC does __not__ align with the semantics of the recent [[rfc: |
Line 124: | Line 122: | ||
- | This RFC does not try to solve as wider use case as the different iterations of [[rfc: | + | This RFC does not try to solve as wide use case as the different iterations of [[rfc: |
- | It's of this author' | + | 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 | + | - There seems to be a higher need in the community |
+ | - Everything Accessors offers beyond disconnected read and write visibility | ||
===== 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 | ||
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 145: | Line 154: | ||
public: | public: | ||
| | ||
- | // Property is writeonly | + | // Property is write-only |
private: | private: | ||
Line 155: | Line 164: | ||
</ | </ | ||
- | The format is "< | + | The format is "< |
- | + | ||
- | + | ||
- | == References == | + | |
- | + | ||
- | Attempting to pass a property value outside of allowed scope as reference, is an error. | + | |
== Reflection == | == Reflection == | ||
- | When using reflection, methods such as "ReflectionProperty:: | + | When using reflection, methods such as '' |
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:: | + | - '' |
- | - ReflectionProperty:: | + | - '' |
- | - ReflectionProperty:: | + | - '' |
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:: | + | - '' |
- | - ReflectionProperty:: | + | - '' |
- | - ReflectionProperty:: | + | - '' |
- | "Reflection:: | + | '' |
//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: | ||
+ | |||
+ | public function __construct(int $id, string $name) { | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 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: | ||
+ | |||
+ | public function __construct(int $id, string $name) { | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | == 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 '' | ||
+ | |||
+ | Furthermore the following method is proposed added to be able to detect readonly properties: | ||
+ | - '' | ||
+ | |||
+ | |||
+ | '' | ||
+ | |||
+ | //TODO: Expand this with specific modifier int for " | ||
- | === 1.2 Language ability to set immutable | + | === 1.3 immutable |
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 254: | ||
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 | + | public immutable |
// [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 265: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | 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-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
== Immutable semantics == | == Immutable semantics == | ||
- | An immutable property may only be written to in __construct() | + | An immutable property may only be written to in construct |
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 214: | Line 293: | ||
== Reflection == | == Reflection == | ||
- | When using reflection, methods such as "ReflectionProperty:: | + | When using reflection, methods such as '' |
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:: | + | - '' |
Line 226: | Line 305: | ||
==== 2. Attributes ==== | ==== 2. Attributes ==== | ||
- | With the recently accepted [[rfc: | + | With the recently accepted [[rfc: |
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 233: | Line 312: | ||
- | ==== 2.1 Readonly attribute | + | === 2.1 Readonly attribute === |
Line 243: | Line 322: | ||
class User { | class User { | ||
<< | << | ||
- | public | + | public |
// This property is not readonly | // This property is not readonly | ||
Line 263: | Line 342: | ||
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 | + | public |
| | ||
// 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 354: | ||
</ | </ | ||
+ | //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 " | ||
- | ==== 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 372: | ||
class User { | class User { | ||
<< | << | ||
- | public | + | public |
public string $email; | public string $email; | ||
Line 310: | Line 392: | ||
<< | << | ||
class User { | class User { | ||
- | public | + | public |
public string $email; | public string $email; | ||
Line 321: | Line 403: | ||
- | //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 / | |
- | ==== 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 | + | |
- | + | ||
- | Alternative would be to propose class level keyword for " | + | |
Line 339: | 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:: | + | While '' |
Line 352: | Line 428: | ||
===== Performance ===== | ===== Performance ===== | ||
- | // | + | // |
===== 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 363: | Line 438: | ||
* [[https:// | * [[https:// | ||
+ | * [[https:// | ||
rfc/readonly_and_immutable_properties.1592741957.txt.gz · Last modified: 2020/06/21 12:19 by andrerom