Re: C# properties vs. accessors RFC

From: Date: Wed, 23 Jan 2013 20:54:09 +0000
Subject: Re: C# properties vs. accessors RFC
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-65123@lists.php.net to get a copy of this message
On Jan 23, 2013, at 1:23 PM, Steve Clay <steve@mrclay.org> wrote: > First of all, I think the functionality provided by Clint and Nikita's RFC [1] is in > demand and would be an asset to PHP, but I also think it can repackaged more simply. > > People are comparing the RFC to C# [2], but while they look similar, C# has a simpler > implementation we should learn from. > > 1. C# draws a firm line between property and field, keeping both concepts simple. > > A "field" is like a PHP property. There's no more to understand. > > A "property" is simply a set of functions emulating a field, and $value is available > in the setter body. There's no more to understand. > > Importantly, I think, the property takes the place of a field; there's never a > "shadow" field of the same name to think about. The obvious downside is you must use a > distinctly-named field for storage, but the upside is conceptual and behavioral simplicity. > There's no need for "guarding" mechanisms and rules about where > "$this->prop" will mean field access or trigger getter/setter; we know there is no > field "prop", period. > > As Sharif Ramadan pointed out, it also makes state snapshots clearer as there is no value > stored under "prop" to potentially confuse. Under the RFC, every property would show up as > a field *even if the accessors didn't use that field*. > > 2. C# has no issetter/unsetter. > > IMO customizing these functions is completely unneeded for the vast majority of use cases and > could be replaced by simpler logic: isset($this->prop) calls the getter and compares to NULL; > unset($this->prop) passes NULL to the setter. > > 3. C# has no auto-implementations. > > IMO auto implementations have some value removing boilerplate, but we should not make them > violate #1. We could have the property syntax specify what field to use for underlying storage, or > simply conclude that the boilerplate is worth the clarity. > > > I think the path forward is to determine how we can serve the same goals as this RFC, but > retain the conceptual simplicity of the C# implementation and maybe syntax that strays less from > current PHP. > > I have some ideas that I could start forging into an RFC. Consider this: > > class Foo { > private $_bar; > public function get bar { return $this->_bar; } > public function set bar { $this->_bar = $value; } > } > > Advantages I see over the RFC: > * It's clearer that the accessors map to regular methods, and you know how to control > visibility of methods and how they're inherited. > * It's clearer $bar doesn't exist as a property, and it will never show up in state > inspection. > * You know $_bar is a plain PHP property, and you can initialize it directly in the > constructor; we don't need an "initter". > * There are no guards/proxies/shadow property to think about > > As for type-hinting, I think that could be achieved by a separate, simpler mechanism: > type-hinting the properties. > > class Foo { > private Bar? $_bar; > } > > $_bar is a regular property, but which can only be set to a Bar or to null ("?" > implies nullable). That gives you simple typed properties (useful and simpler to understand without > accessors), but also suggests how to combine these to get "typed accessors": > > class Foo { > // settable anywhere > public Bar $bar; > > // "read only" > protected Baz? $_baz; > public function get baz { return $this->_baz; } > } > > > Down the road we could further address how to shorten this syntax but while keeping it clear > that accessors are just functions and properties are just value stores. > I'd just like to point out the fact that RFC v1.1 from a year ago was exactly as above but people wanted all of these other features. They were not a property, they had no "guarding", no unset, isset, etc. The original RFC that was exactly as c# had it, nobody liked it. It was changed to its current incarnation because it now mimics exactly what everyone is use to with __get(), etc. > > [1] https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 > [2] > http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx > > Steve Clay > -- > http://www.mrclay.org/ > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >

« previous php.internals (#65123) next »