On Thu, Feb 20, 2020 at 1:27 AM Matthew Brown <matthewmatt...@gmail.com> wrote:
> Someone recently requested something similar for a PHP static analysis tool > I wrote (https://psalm.dev/r/f75997a263), though that version only allows > lazy initialisation inside the class in which a given property is declared. > > Personally I don't like either approach – I think per-property getters and > setters would be a more appropriate venue for this functionality, something > like: > > property int $s { > public get; > private set; > } > > This pattern could also be extended to support per-property getter and > setter methods. > While I certainly like the idea of per-property getters/setters, I think that both of these have their place. This RFC proposes readonly properties, that can be initialized once, and then never modified again, even within the same class. Getters/setters only provide the possibility of having asymmetric visibility: They prevent modifying the property from outside the class, but it can still be modified inside the class. In that, readonly properties offer a stronger guarantee. Of course, that does leave the question of how often you need one or the other. Maybe just the asymmetric visibility is sufficient for most practical purposes, in which case it may not be worthwhile to introduce readonly properties as a separate feature. Two comments on the specifics of the RFC: The RFC allows specifying a default value for readonly properties. However, a property for which a default value has been specified will always have that value, as it cannot be overwritten in the constructor. If you write "public readonly int $foo = 42", then $object->foo is *always* going to be 42. I'm not sure what that would ever be useful for, and it seems like something that is bound to be confusing. Maybe it would make more sense to forbid readonly properties with default values? (That way, the rule that readonly properties have to be typed falls out naturally as well -- untyped properties always have a default.) Regarding the keyword choice, I think you can drop "sealed" from the list, as it is an established term that affects inheritance, not mutability. Of the choices you present, "immutable", "readonly" and "writeonce" seem like the most viable candidates. "writeonce", while the one that is most technically accurate, is also *unnecessarily* technically accurate and not intuitive. From the perspective of an API consumer, I think that "readonly" is the most accurate description of how they are supposed to interact with the property. The API contract you want to expose is that they can only read from the property, not write to it. Calling it "writeonce" would be quite confusing in that context, because the API consumer is never expected to write to the property. In the majority of cases you will be providing fully initialized objects, in which case they are indeed readonly for the consumer -- the details of the write-once property are only relevant in special cases like ReflectionClass::newObjectWithoutConstructor() for serialization libraries, or lazy initialization like in Marco's ProxyManager. Regards, Nikita > On Wed, 19 Feb 2020 at 12:06, Máté Kocsis <kocsismat...@gmail.com> wrote: > > > Hi Internals, > > > > I'd like to move my RFC forward to the discussion phase: > > https://wiki.php.net/rfc/write_once_properties > > > > In short, I propose to add support for a new property modifier that would > > allow properties to be initialized, but not modified afterwards. > > > > Cheers, > > Máté Kocsis > > >