> > Maybe I didn't understand what you mean, but if you want property > references, why not just use, well, property references?
Property-references don't know what property they're referencing - they reference the object/value held by the property, not the property itself. If you want more than just get/set, but also info on the property, why not > pass a ReflectionProperty or a modification thereof which has a pre-bound > object? Why do you need a new operator for this That's what we have to do currently - that's why form-helpers and ORMs currently rely on strings for property-references... echo $form->textInput($user, 'email'); This example is fairly straight forward, and PHP developers are probably used to reading code like this by now - but the meaning becomes increasingly obscured the further you take things out of context: $form = new FormHelper($user); echo $form->textInput('email'); Now you have to think a little more to understand what's going on - the API is more convenient now, but more obscured. It's also less flexible, since now you have to manually switch objects or create more form-helpers to handle more than one object. echo $form->textInput($property_name); Even more obscured, since now your local variable is definitely a string, and you can no longer see which property we're talking about. The root of this problem is the fact that 'email' is a string - the fact that it references a source-code element is something that is merely implied but can't be proven, which means you can't have proper IDE support or static analysis. (by other means than sheer guesswork.) As opposed to: echo $form->textInput(^$user->email); There is no question that you're referring to an object property here - it's not a string and it's also an atomic reference to a particular object and property combined, as opposed to the string and object as a detached reference and value pair. Even if you have to pass these around: class FormHelper { public function textInput(PropertyReference $prop) { return $this->renderInput('text', $prop); } protected function renderInput($type, PropertyReference $prop) { .... } } You're no longer passing around a string detached from it's object context, having to keep the object-reference as state or pass it around as a separate argument from the property-name - the idea is to have formal language-level support for a reference to an object property. Yes, you can do that with strings and the Reflection API now - the point is not whether or not it can already be done, the point is to make it part of the language, so that you can use it based on more than just ideas and assumptions, and so we can build libraries and applications with proper IDE support. Current codebases rely heavily on conventions and APIs - many popular meta-programming techniques could be simplified and made more elegant, easier to understand without having to learn conventions, faster to use, and with support for static analysis. - Rasmus Schultz On Thu, Apr 25, 2013 at 9:22 AM, Nikita Popov <nikita....@gmail.com> wrote: > On Thu, Apr 25, 2013 at 2:47 PM, Rasmus Schultz <ras...@mindplay.dk>wrote: > >> Okay, >> >> No one seemed extremely interested in my notes about static >> type-references<http://marc.info/?t=136327849600002&r=1&w=2>- I want >> >> to bring up something closely related that could possibly be even >> more useful, in particular for things like form-helpers, which remains as >> one of the things that just can't be done in PHP as elegantly as it can in >> some other languages. >> >> I'm not sure if de-referencing is the correct term? I'm talking about the >> ability to use a property-reference indirectly - meaning, don't read the >> property, don't write the property, but reference the property in a way >> that permits you to read/write the property later on. >> >> In this example, I'm using ^ as the de-reference operator: >> >> class User >> { >> public $email; >> } >> >> $user = new User(); >> >> $form = new FormHelper($user); >> >> echo $form->textInput(^$user->email); >> >> Note the ^ operator in the last line - we're not passing the value of >> $user->email to FormHelper::textInput() but a reference to it... assuming >> a >> new internal PropertyReference class, it's declaration might look like >> this: >> >> class FormHelper >> { >> public function textInput(PropertyReference $prop) >> { >> $name = $prop->className . '[' . $prop->propertyName . ']'; >> $value = $prop->getValue(); >> >> return "<input type='text' name='{$name}' value='{$value}' />"; >> } >> >> .... >> } >> >> >> The new PropertyReference class might have an interface like the >> following: >> >> class PropertyReference >> { >> public readonly object $object; // the object that was referenced >> public readonly string $className; // the type of object that was >> referenced >> public readonly string $propertyName; // the name of the property that >> was referenced >> >> public function getValue(); // read and return the property-value >> public function setValue($value); // write the property-value >> } >> >> >> For a statement like this: >> >> $prop = ^$user->email; >> >> The ^ operator does something equivalent to: >> >> $prop = new PropertyReference(); >> >> $prop->object = $user; >> $prop->className = get_class($user); >> $prop->propertyName = 'email'; >> >> $prop->getValue = function () use ($user) { >> return $user->email; >> }; >> >> $prop->setValue = function ($value) use ($user) { >> $user->email = $value; >> }; >> >> >> So essentially, you get all the information about the object and property, >> and a way to read/write that property, with one character - something that >> would enable hugely convenient APIs for things like form-helpers, >> data-mappers and object/relational-mappers. >> >> When the object-type is known in IDEs (as it is in properly documented >> code) this also addresses the same issue as static type-references, >> allowing for static analysis and automated refactoring, but with a much >> shorter and more convenient syntax - not needing to explicitly reference >> the class-name, and with the added benefit of knowing the instance, both >> of >> which are hugely important for form-helpers and mappers. >> >> Note that the getValue() and setValue() closures resolve properties the >> usual way - that is, you can de-reference magic properties too, since no >> attempt is made to read or write the property until getValue() or >> setValue() is made. >> >> Most use-cases for referencing class and property-names are situations >> like >> these, so this kind of kills two birds with one stone - a static way to >> reference properties, but with the addition of providing the actual >> object-context. And the shortest possible syntax. >> >> What do you think? >> >> - Rasmus Schultz >> > > Maybe I didn't understand what you mean, but if you want property > references, why not just use, well, property references? > > function foo(&$ref) { $ref = 'a'; } > > $a = new Obj; > foo($a->prop); > var_dump($a->prop) // string(1) "a" > > Also works for magic properties, assuming your correctly declared them > using &__get. > > If you want more than just get/set, but also info on the property, why not > pass a ReflectionProperty or a modification thereof which has a pre-bound > object? Why do you need a new operator for this? > > Nikita >