On Tue, May 4, 2021, at 5:33 AM, Nikita Popov wrote: > Hi internals, > > I'd like to present an RFC for property accessors: > https://wiki.php.net/rfc/property_accessors > > Property accessors are like __get() and __set(), but for a single property. > They also support read-only properties and properties with asymmetric > visibility (public read, private write) as a side-effect. > > The proposal is modeled after C#-style accessors (also used by Swift), and > syntactically similar to the previous > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > While I put a lot of effort into both the proposal and the implementation, > I've grown increasingly uncertain that this is the right direction for us > to take. The proposal turned out to be significantly more complex than I > originally anticipated (despite reducing the scope to only "get" and "set" > accessors), and I'm sure there are some interactions I still haven't > accounted for. I'm not convinced the value justifies the complexity. > > So, while I'm putting this up for discussion, it may be that I will not > pursue landing it. I think a lot of the practical value of this accessors > proposal would be captured by support for read-only (and/or private-write) > properties. This has been discussed (and declined) in the past, but > probably should be revisited. > > Regards, > Nikita
This is an amazingly detailed RFC, and I love most of it. Thank you, Nikita! Regarding complexity, can you elaborate on what the most complex/tricky/problematic parts are? I'm mainly wondering if there are any parts that could be changed/slightly scaled back that would reduce the complexity more than it reduces capability. (Eg, removing guard and lazy for now is a good call, IMO, since both can be emulated with the other two.) All else equal, though, I would favor including all of it. I would say that the visibility controls get us 70% of the benefit, not 80/90%, but I do agree that those are hugely beneficial in and of themselves. *IF* you decide to scale it back, I would strongly recommend simply dropping the explicit accessors support and leaving the rest of the syntax the same. That way we know it's forward-compatible should we decide in the future to re-introduce explicit accessors. Some other questions: 1. Do setters have arbitrary access to the object? Can they read/set arbitrary other values? I'm thinking of something like this: class Person { private string $firstName; private string $lastName; private string $nickname; private int $age; public string $fullName { get { return "$this->firstName $this->lastName"; } set($fullName) { if ($this->age > 50) throw new Exception('You are too old to change your name.'); [$this->firstName, $this->lastName] = explode(' ', $fullName); $this->nickname = substr(0, 5, $this->firstName); } } } (A contrived example, obviously.) 2. My knee-jerk thought is to agree with Marco and avoid references entirely, for the sake of everyone's sanity. However, it is implied that &get is the only way to properly handle array property accessors. Am I understanding that correctly? If not, can you expand on array handling? I'd happily jettison references if arrays can still be supported nicely without them. 3. The partial incompatibility with constructor promotion is understandable, but disappointing. Is it at all possible to modify the promotion logic such that if a property is already defined with accessors, you can still promote it without a syntax error? I am thinking of this case: class Test { private int _$foo; public int $foo { get { return $this->_foo; } set ($foo) { if ($foo < 0) throw new InvalidArgumentException('Must be positive.'); $this->_foo = $foo; } } public function __construct(public int $foo) {} } (Though a guard would be nicer, as it avoids the second variable, but there are other considerations there.) 4. I still don't love $value being a magic name in setters. Being able to specify it explicitly is nice, and I would probably always use that myself (and push for it in coding standards), but would it be feasible to default it instead to the name of the variable? Since that variable name cannot be a backing variable, we know that it won't conflict with anything, but it would be more self-documenting. Thanks again, and I do hope you can be convinced all this effort is worth bringing to a vote. :-) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php