# [RFC] Property Accessors v1.2 : Internal Accessor Method Visibility / Callability

- Thread: https://externals.io/message/63640
- Original archive: https://news-web.php.net/php.internals/63640
- Started by Clint Priest on 2012-10-26T10:37:26+00:00
- Messages: 49
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/63640.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #63640 — Clint Priest — 2012-10-26T10:37:26+00:00

URL: https://externals.io/message/63640#63640

I'm opening up several new threads to get discussion going on the 
remaining "being debated" categories referenced in this 1.1 -> 1.2 
change spec:
https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented/change-requests

------------------------------------------------------------------------
Some people are in favor of the internal functions being generated by an 
accessor declaration should be invisible and non-callable directly. 
Others are in favor of leaving them visible and callable.

*Type 1 ( Userland Programmer )**
*
As a userland programmer, someone who cares nothing for "how" php works, 
only how their own code works. If they define an accessor they expect to 
see an accessor, reflection should reflect that there are accessors and 
no other "methods" they did not explicitly define. If they were to 
reflect on all of the methods of their class and see a number of 
__getHours() they may be confused as to why or where this function came 
from. From their perspective, they have defined an accessor and "how" 
that accessor works on the inside is of no importance to them and only 
seeks to complicate or confuse matters when they are exposed to these 
"implementation details" of the php language its-self. If you tried to 
set a value such as $obj?abc = 1 through an accessor which could not be 
set, you would probably want to see an error like: Warning, cannot set 
Class?abc, no setter defined.

*Type 2 ( Internals Programmer )**
*
As an internals programmer, you want nothing hidden from you. If an 
accessor implements special __getHours() methods to work its magic, then 
you want to see them, you want to call them directly if you so choose. 
In effect you want nothing hidden from you. In this case you probably 
don't even want Reflection to reflect accessors as anything different 
than specially formatted and called methods on the class. This can be 
understandable because you want all information available to you. You 
would probably not be confused if you wrote $obj?abc = 1 and got back an 
error like "Fatal Error: Class->__setAbc() function does not exist.

*Unfortunately 80 to 95% of all people who use PHP are of the first type.**
*
Revealing these internal matters to them would only leave them confused, 
possibly frustrated and likely asking about it to the internals mailing 
list to answer (repeatedly).
------------------------------------------------------------------------

Thoughts?

-- 
-Clint

---

## #63645 — Maciek Sokolewicz — 2012-10-26T11:47:01+00:00

URL: https://externals.io/message/63640#63645 · In reply to: #63640

> ------------------------------------------------------------------------
> Some people are in favor of the internal functions being generated by an
> accessor declaration should be invisible and non-callable directly.
> Others are in favor of leaving them visible and callable.
>
> *Type 1 ( Userland Programmer )**
> *
> As a userland programmer, someone who cares nothing for "how" php works,
> only how their own code works. If they define an accessor they expect to
> see an accessor, reflection should reflect that there are accessors and
> no other "methods" they did not explicitly define. If they were to
> reflect on all of the methods of their class and see a number of
> __getHours() they may be confused as to why or where this function came
> from. From their perspective, they have defined an accessor and "how"
> that accessor works on the inside is of no importance to them and only
> seeks to complicate or confuse matters when they are exposed to these
> "implementation details" of the php language its-self. If you tried to
> set a value such as $obj?abc = 1 through an accessor which could not be
> set, you would probably want to see an error like: Warning, cannot set
> Class?abc, no setter defined.
>
> *Type 2 ( Internals Programmer )**
> *
> As an internals programmer, you want nothing hidden from you. If an
> accessor implements special __getHours() methods to work its magic, then
> you want to see them, you want to call them directly if you so choose.
> In effect you want nothing hidden from you. In this case you probably
> don't even want Reflection to reflect accessors as anything different
> than specially formatted and called methods on the class. This can be
> understandable because you want all information available to you. You
> would probably not be confused if you wrote $obj?abc = 1 and got back an
> error like "Fatal Error: Class->__setAbc() function does not exist.
>
> *Unfortunately 80 to 95% of all people who use PHP are of the first type.**
> *
> Revealing these internal matters to them would only leave them confused,
> possibly frustrated and likely asking about it to the internals mailing
> list to answer (repeatedly).
> ------------------------------------------------------------------------
>
> Thoughts?
>

I personally don't think there's such a huge difference between the two 
'groups'. When people in group 1 use reflection to examine their 
accessors, they should have enough knowledge to understand how accessors 
are implemented. If we document it well, I don't really see that as a 
problem.

- Tul

---

## #63646 — Steve Clay — 2012-10-26T13:44:42+00:00

URL: https://externals.io/message/63640#63646 · In reply to: #63640

> https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented/change-requests
> ------------------------------------------------------------------------
> Some people are in favor of the internal functions being generated by an accessor
> declaration should be invisible and non-callable directly. Others are in favor of leaving
> them visible and callable.

If we leave them callable,

* What would be the effects of users defining the "internal" methods (in both cases of 
if/if not the accessor is also defined)? Considering current magic methods are 
*purposefully designed* to be implemented by the user, I expect users to try this and, if 
it works, release code with it.

* I assume one could use them as regular methods?
    * call_user_func([$foo, '__getpropName']);
    * $foo->{"__get$propName"}

I apologize if these were already covered.

Steve Clay
-- 
http://www.mrclay.org/

---

## #63647 — Stas Malyshev — 2012-10-26T14:14:33+00:00

URL: https://externals.io/message/63640#63647 · In reply to: #63640

Hi!

> Some people are in favor of the internal functions being generated by an 
> accessor declaration should be invisible and non-callable directly. 
> Others are in favor of leaving them visible and callable.

I think these types are not right. It has nothing to do with
internals/userland, it has to do with wanting more magic that work is a
complex way while allowing user no knowledge and control over what's
going on, or reduced number of simple concepts that interact in a
variety of ways. You can say it's Windows model vs. Unix model, if you
need monikers.

> *Type 1 ( Userland Programmer )**
> *
> As a userland programmer, someone who cares nothing for "how" php works, 
> only how their own code works. If they define an accessor they expect to 
> see an accessor, reflection should reflect that there are accessors and 

Again, this insists on the notion that there's such accepted thing as
"accessor" in PHP field, which already has a known behavior and set of
expectations, and these match exactly the proposal of "invisible". But
this is not true at all - only successors existing so far in PHP are
regular perfectly visible methods. So if you expect to see an accessor,
you expect to see __get. If you appeal to natural expectations of PHP
user, you can not argue it is "for accessors to be accessors", because
PHP has never had anything like you proposed, and there's no any
accepted definition of "accessor" that implies what you are implying.

> no other "methods" they did not explicitly define. If they were to 
> reflect on all of the methods of their class and see a number of 
> __getHours() they may be confused as to why or where this function came 

Please do not insult the intelligence of PHP users. They are not some
mindless creatures that given property Hours, previous existence of
__get and __getHours can not figure out what's going on, even after
being told of the new accessors feature (since they're using it in the
code). They won't be confused. Nobody knowing how to program a
hello-world would. This mythical easily-confusable users do not exist,
but if they did, they'd just not use reflection because it'd be too
confusing for them anyway.

> than specially formatted and called methods on the class. This can be 
> understandable because you want all information available to you. You 

This has very little to do with information available. This has
everything to do with

> would probably not be confused if you wrote $obj?abc = 1 and got back an 
> error like "Fatal Error: Class->__setAbc() function does not exist.

You can very easily handle the error in the same handler that you look
for setter, this is not an issue at all. In general, error messages have
very little to do with the whole thing. If the error messages is the
thing you're worried about - it should be trivially easy to fix, since
all access will go through object handlers anyway, and the object
handler would decide to throw the error - so you'd be able very easily
to issue any error message you like.

> *Unfortunately 80 to 95% of all people who use PHP are of the first type.**

Not really. There are a lot of programmers that aren't Windows type, and
prefer simple interfaces to ones with a lot of complicated magic. --
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63653 — Patrick Schaaf — 2012-10-26T17:41:51+00:00

URL: https://externals.io/message/63640#63653 · In reply to: #63640

I'm all for having the "internal" methods being totally normal magic
methods, for the reduced complexity reasons already mentioned.

I would also expect to be able to simply define such a magic method myself,
and have it behave in just the same way as when defining it using the
accessor declaration syntactic sugar.

To formulate it a different way: first expand on the current __get/__set
magic methods by clearly documenting a new set of per-property-name magic
methods, and the rules when they are called. Then on top of that, introduce
and document the accessor declaration syntactic sugar.

One point that came up some time ago, I'd like to mention again: there is
already a magic method named __set_state which would collide head on with
an accessor setter method for a property $_state IF that method would
follow the __set$PROPNAME pattern. As a solution for that, I'd propose
naming the new magic methods with a so-far-not-taken common prefix: __prop
- i.e. name them __prop_get_xxx, __prop_set_xxx, and so on.

best regards
  Patrick

---

## #63655 — Nikita Popov — 2012-10-26T20:18:04+00:00

URL: https://externals.io/message/63640#63655 · In reply to: #63647

> Hi!
>
> > […]
>
> I think these types are not right. It has nothing to do with
> internals/userland, it has to do with wanting more magic that work is a
> complex way while allowing user no knowledge and control over what's
> going on, or reduced number of simple concepts that interact in a
> variety of ways.
I think you are presenting the situation inaccurately. This has
nothing to do with complex magic and also does not intend to limit the
users control. Actually, both approaches are exactly the same, the
only difference is whether we additionally put the accessor function
into the method table or whether we do not.

I still fail to see where you see complexity come into the picture.
You have mentioned inheritance checking, but from what I see the
functions doing the inheritance check take generic zend_function*s, so
they wouldn't have a problem dealing with code not in the method
table. The same applies to pretty much everything else too. After all,
there *is* a reason why we have abstractions in the engine ;)

To me the situation is as simple as this: I declared a get accessor
for $foo. I did not declare the method __getfoo(). So why is that
method there?

It seems really pointless, counter-intuitive and hacky to me to
automatically create methods that do not actually exist (not under
that name at least).

Nikita

---

## #63656 — Stas Malyshev — 2012-10-26T20:34:47+00:00

URL: https://externals.io/message/63640#63656 · In reply to: #63655

Hi!

> users control. Actually, both approaches are exactly the same, the
> only difference is whether we additionally put the accessor function
> into the method table or whether we do not.

They may be almost the same technically, but very different
conceptually. Your approach means we introduce new complex concept of
not-quite-method, which can be called only in some special
circumstances, has special handling by compiler, backtraces, reflection,
tools, etc. and requires people to learn this new concept and be always
aware of it to be able to correctly operate it. My approach is that you
just have another magic method, which we already have plenty in PHP, and
does not require any new concepts introduced, and works very similar to
existing access magics.

> I still fail to see where you see complexity come into the picture.

Described above. You want to introduce new entity into PHP called
"accessor", which looks like PHP method, but lives outside of the PHP
method table, is not callable by regular means (though might be callable
by special means, but you have no way to use methods' reflection to know
if such call would succeed or not) and requires special considerations.
This is more complex than using already existing concepts, by definition
- more concepts is more complex than less concepts.

> You have mentioned inheritance checking, but from what I see the
> functions doing the inheritance check take generic zend_function*s, so
> they wouldn't have a problem dealing with code not in the method
> table. The same applies to pretty much everything else too. After all,
> there *is* a reason why we have abstractions in the engine ;)

They won't have a problem. They won't deal with these not-quite-methods.
That's exactly the problem - we already have mechanism of dealing with
inheritance, and you propose to introduce another one to deal with
additional complexity of methods not in method table.

> To me the situation is as simple as this: I declared a get accessor
> for $foo. I did not declare the method __getfoo(). So why is that
> method there?

This in not simple. You know what "accessor" is. The other 100% of PHP
users have no idea what "accessor" is. They know what methods are, they
know what magics are. So if I tell them "we have extensions of __get
that allow you to do __getFoo" - they instantly know what's going on. If
I tell them "we have accessors" - they'd have to go and read the manual
to understand what is going on and which additional restriction you
placed on them in order to force them into your preconception of
"accessor".

> It seems really pointless, counter-intuitive and hacky to me to
> automatically create methods that do not actually exist (not under
> that name at least).

What you mean by "do not actually exist"? Of course they exist, that's
the whole point. You will be running them, how they don't exist? You
just want hide their existence by introducing a bunch of complex checks
all over the engine under the premise that showing the user the real
methods in function table would "confuse" them. It won't. The only thing
it would do is contradict your idea that there's some definition of
"accessors" that requires them to not be methods. I see no reason for
such definition. It is an option, but having them as methods is an
option too, and in my opinion a much better one.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63657 — Stas Malyshev — 2012-10-26T20:37:10+00:00

URL: https://externals.io/message/63640#63657 · In reply to: #63653

Hi!

> an accessor setter method for a property $_state IF that method would
> follow the __set$PROPNAME pattern. As a solution for that, I'd propose
> naming the new magic methods with a so-far-not-taken common prefix: __prop
> - i.e. name them __prop_get_xxx, __prop_set_xxx, and so on.

I think it'd more natural to make it __set__PROPNAME. Though __set_state
is a static method, so maybe we can live with it - except that you won't
be able to declare property named $_state.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63658 — Nikita Popov — 2012-10-26T21:21:25+00:00

URL: https://externals.io/message/63640#63658 · In reply to: #63656

> Hi!
>
> > […]
>
> They may be almost the same technically, but very different
> conceptually. Your approach means we introduce new complex concept of
> not-quite-method, which can be called only in some special
> circumstances, has special handling by compiler, backtraces, reflection,
> tools, etc. and requires people to learn this new concept and be always
> aware of it to be able to correctly operate it. My approach is that you
> just have another magic method, which we already have plenty in PHP, and
> does not require any new concepts introduced, and works very similar to
> existing access magics.
>
> > […]
>
> Described above. You want to introduce new entity into PHP called
> "accessor", which looks like PHP method, but lives outside of the PHP
> method table, is not callable by regular means (though might be callable
> by special means, but you have no way to use methods' reflection to know
> if such call would succeed or not) and requires special considerations.
> This is more complex than using already existing concepts, by definition
> - more concepts is more complex than less concepts.
>
> > […]
>
> They won't have a problem. They won't deal with these not-quite-methods.
> That's exactly the problem - we already have mechanism of dealing with
> inheritance, and you propose to introduce another one to deal with
> additional complexity of methods not in method table.
>
> > […]
>
> This in not simple. You know what "accessor" is. The other 100% of PHP
> users have no idea what "accessor" is. They know what methods are, they
> know what magics are. So if I tell them "we have extensions of __get
> that allow you to do __getFoo" - they instantly know what's going on. If
> I tell them "we have accessors" - they'd have to go and read the manual
> to understand what is going on and which additional restriction you
> placed on them in order to force them into your preconception of
> "accessor".
>
> > […]
>
> What you mean by "do not actually exist"? Of course they exist, that's
> the whole point. You will be running them, how they don't exist? You
> just want hide their existence by introducing a bunch of complex checks
> all over the engine under the premise that showing the user the real
> methods in function table would "confuse" them. It won't. The only thing
> it would do is contradict your idea that there's some definition of
> "accessors" that requires them to not be methods. I see no reason for
> such definition. It is an option, but having them as methods is an
> option too, and in my opinion a much better one.

Stas, if you define an accessor, how do you define it? Do you say

     public $foo {
          get() { ... }
          set($value) { ... }
     }

or do you say

     public function __getFoo() { ... }
     public function __setFoo($value) { ... }

?

According to the current proposal at least you can write the first
code *and the first code only*. If you write the second code then you
define two methods __getFoo and __setFoo and nothing more. Those
methods will not be called when you write $bar->foo. If just defining
the methods would cause $bar->foo to be intercepted, *then* __getFoo
etc would indeed be just magic methods with "dynamic" names. But as
already said, this is not the case, so you would have
magic-methods-which-aren't-really-magic-methods (extra for you, as you
like the term not-quite-method so much ^^).

You keep saying that the term "accessors" would be somehow a lot
harder to understand for users and that telling them something about
__getFoo and __setFoo will be easier to grasp. I don't know about you,
but I think that if you want to explain this new shiny feature to a
user you would start off with a code like public $foo { get() { ... }
... } and explain that that those are accessors and are used to define
special behavior for properties. You probably won't start off with
telling them that this declaration is automatically converted to a set
of __getFoo methods which are registered as handlers for the accessor.
I really don't see how going into details like __getFoo makes anything
easier.

:)
Nikita

---

## #63659 — Stas Malyshev — 2012-10-26T23:37:06+00:00

URL: https://externals.io/message/63640#63659 · In reply to: #63658

Hi!

> Stas, if you define an accessor, how do you define it? Do you say

Either way, doesn't matter.

> According to the current proposal at least you can write the first
> code *and the first code only*. If you write the second code then you

That's where I think it is wrong. It would be much simpler and
consistent with existing PHP if it were a natural extension of __get
instead of a completely new and foreign concept.

> special behavior for properties. You probably won't start off with
> telling them that this declaration is automatically converted to a set
> of __getFoo methods which are registered as handlers for the accessor.
> I really don't see how going into details like __getFoo makes anything
> easier.

Depending on your purpose and background. If you know how __get works,
extrapolating to __getFoo is trivial. Getting special syntax that
produces __getFoo from this is also trivial.

Getting the concept of methods that are not quite methods and get called
only through special intercept mechanism and have special backtrace
rewriting engine and reflection hiding patches so you can be inside the
method that officially does not exist - not so trivial.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63661 — Patrick Schaaf — 2012-10-27T08:01:39+00:00

URL: https://externals.io/message/63640#63661 · In reply to: #63657

> > […]
>
> I think it'd more natural to make it __set__PROPNAME. Though __set_state
> is a static method, so maybe we can live with it - except that you won't
> be able to declare property named $_state.

Needing an "except" is inelegant, if it can be avoided up front.

Also, having __prop_get_XXX etc. is a bit more descriptive to somebody
later "wondering" what these methods are - prop alludes to properties,
which is what the methods are about. I can already see the stack overflow
subject, "what are these __prop methods in new PHP" :)

best regards
  Patrick

---

## #63669 — Clint Priest — 2012-10-27T18:05:27+00:00

URL: https://externals.io/message/63640#63669 · In reply to: #63661

That's why I think they shouldn't even be visible to users, they aren't 
relevant to them and in fact it could mis-lead them into thinking that 
they could simply define __getHours() and expect $foo->Hours to call 
it, which it wouldn't.

To me, the bottom line is, the fact that there are methods defined by 
accessors is an engine detail and not something that should be exposed 
to the user.

As for the __set_state() issue, I can see the need to change the 
pattern of method naming, I'd be amenable to anything.

Everyone okay with __get_prop_hours() naming convention then?


> > […]
>
> Needing an "except" is inelegant, if it can be avoided up front.
>
> Also, having __prop_get_XXX etc. is a bit more descriptive to somebody
> later "wondering" what these methods are - prop alludes to properties,
> which is what the methods are about. I can already see the stack overflow
> subject, "what are these __prop methods in new PHP" :)
>
> best regards
>    Patrick
>

--
-Clint

---

## #63670 — Clint Priest — 2012-10-27T18:14:53+00:00

URL: https://externals.io/message/63640#63670 · In reply to: #63659

> Hi!
>
> > […]
> Either way, doesn't matter.
>
> > […]
> That's where I think it is wrong. It would be much simpler and
> consistent with existing PHP if it were a natural extension of __get
> instead of a completely new and foreign concept.
>
> > […]
> Depending on your purpose and background. If you know how __get works,
> extrapolating to __getFoo is trivial. Getting special syntax that
> produces __getFoo from this is also trivial.
>
> Getting the concept of methods that are not quite methods and get called
> only through special intercept mechanism and have special backtrace
> rewriting engine and reflection hiding patches so you can be inside the
> method that officially does not exist - not so trivial.
The only thing that does back patching is for static accessors and 
you've already pointed out that what I was doing to make that happen is 
just going to break and fail in so many ways.

What is "reflection hiding patches" referring to?  Reflection is changed 
to reflect what the user has defined, that's what reflection is supposed 
to be.. no?

Lastly, this idea that accessors is such a foreign concept is a bit 
ridiculous.  You'd be hard pressed to find a modern/popular language 
these days that doesn't have them, so if someone is confused about what 
an accessor is then they probably have their head in the sand, god 
forbid they'd have to read the manual.

-- 
-Clint

---

## #63671 — Patrick Schaaf — 2012-10-27T19:14:58+00:00

URL: https://externals.io/message/63640#63671 · In reply to: #63669

On Saturday 27 October 2012 13:05:27 Clint Priest wrote:
> That's why I think they shouldn't even be visible to users, they aren't
> relevant to them and in fact it could mis-lead them into thinking that
> they could simply define __getHours() and expect $foo->Hours to call
> it, which it wouldn't.

I would expect / want it to do so.

I see it this way:

Defining semantics for magic methods named __prop_get_XXX, __prop_set_XXX etc 
as a specialization of __get/__set used whenever they exist for a given $XXX, 
is in my eyes a complete, proper accessor enhancement, saving me from doing a 
switch dance in __get/__set. The implementation should be absolutely 
straightforward, in the place where a missing property now tests for existence 
of __get/__set, a first, additional test for the specifically named 
__prop_get_XXX method would be added.

Your proposed accessor _syntax_ is purely syntactic sugar, implementable on 
top of the functionality of the previous paragraph and implemented in terms of 
automatic code generation for it. This syntactic sugar could be separately 
implemented, discussed in a separate RFC,etc.

The added complexity that I see, and I think Stas has meant to mention a lot 
of times, is everything - all code and documentation and explanation - that 
stems from NOT making it that two-step process. And in my opinion that would 
be completely superfluous, as it brings neither functionality nor syntax, just 
random additional issues.

best regards
  Patrick

---

## #63674 — Stas Malyshev — 2012-10-27T20:21:35+00:00

URL: https://externals.io/message/63640#63674 · In reply to: #63669

Hi!

> That's why I think they shouldn't even be visible to users, they aren't 
> relevant to them and in fact it could mis-lead them into thinking that 
> they could simply define __getHours() and expect $foo->Hours to call 
> it, which it wouldn't.

I think it should. That's how __get works.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63675 — Stas Malyshev — 2012-10-27T20:28:29+00:00

URL: https://externals.io/message/63640#63675 · In reply to: #63670

Hi!

> What is "reflection hiding patches" referring to?  Reflection is changed 
> to reflect what the user has defined, that's what reflection is supposed 
> to be.. no?

No. Reflection is supposed to show which methods exist on a class, which
can be called from certain context, etc. This has nothing to do with
where they were defined.

> Lastly, this idea that accessors is such a foreign concept is a bit 
> ridiculous.  You'd be hard pressed to find a modern/popular language 
> these days that doesn't have them, so if someone is confused about what 

PHP doesn't have them. Also, by your definition, Python doesn't have
them - in Python, __ methods are regular methods. Also, by your
definition, Ruby doesn't have them either - in Ruby, you define them as
regular methods, and you very well can call them too:
http://stackoverflow.com/questions/621176/how-to-dynamically-call-accessor-methods-in-ruby#621193.
Javascript doesn't have them either. Java doesn't have them either. So
I'm not that hard pressed to find languages that don't follow your
model, as you can see.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63677 — Clint Priest — 2012-10-28T00:42:01+00:00

URL: https://externals.io/message/63640#63677 · In reply to: #63671

Sounds like you're implying that the mere existence of a properly named 
function such as __prop_get_hours() would cause it to be called instead 
of returning the property.

There are several problems with this approach:

1) Currently __get() is only checked/invoked if there is not a property 
already defined; ie properties shadow __get() (no performance penalty)

2) It would dramatically reduce performance because every property 
access would have to create the function string, get it's hash value and 
do a hash look up against the function table, just to see if there is a 
properly named accessor function.  Failing that it would then check for 
the existence of a property and failing that move on to looking up __get

-Clint


> On Saturday 27 October 2012 13:05:27 Clint Priest wrote:
> > […]
> I would expect / want it to do so.
>
> I see it this way:
>
> Defining semantics for magic methods named __prop_get_XXX, __prop_set_XXX etc
> as a specialization of __get/__set used whenever they exist for a given $XXX,
> is in my eyes a complete, proper accessor enhancement, saving me from doing a
> switch dance in __get/__set. The implementation should be absolutely
> straightforward, in the place where a missing property now tests for existence
> of __get/__set, a first, additional test for the specifically named
> __prop_get_XXX method would be added.
>
> Your proposed accessor _syntax_ is purely syntactic sugar, implementable on
> top of the functionality of the previous paragraph and implemented in terms of
> automatic code generation for it. This syntactic sugar could be separately
> implemented, discussed in a separate RFC,etc.
>
> The added complexity that I see, and I think Stas has meant to mention a lot
> of times, is everything - all code and documentation and explanation - that
> stems from NOT making it that two-step process. And in my opinion that would
> be completely superfluous, as it brings neither functionality nor syntax, just
> random additional issues.
>
> best regards
>    Patrick
>

-- 
-Clint

---

## #63678 — Clint Priest — 2012-10-28T00:48:06+00:00

URL: https://externals.io/message/63640#63678 · In reply to: #63675

Stas, you should probably do some research before posting such non-sense:

http://en.wikipedia.org/wiki/Property_%28programming%29

Every language you mentioned has them.  Perhaps the confusion is that I 
am calling them accessors since other languages refer to accessors as 
"properties" while PHP refers to "properties" the way that other 
languages refer to them as "fields" or "data members."

By accessors I am simply referring to getters, setters (and in the case 
of php, issetter and unsetter).


> Hi!
>
> > […]
> No. Reflection is supposed to show which methods exist on a class, which
> can be called from certain context, etc. This has nothing to do with
> where they were defined.
>
> > […]
> PHP doesn't have them. Also, by your definition, Python doesn't have
> them - in Python, __ methods are regular methods. Also, by your
> definition, Ruby doesn't have them either - in Ruby, you define them as
> regular methods, and you very well can call them too:
> http://stackoverflow.com/questions/621176/how-to-dynamically-call-accessor-methods-in-ruby#621193.
> Javascript doesn't have them either. Java doesn't have them either. So
> I'm not that hard pressed to find languages that don't follow your
> model, as you can see.

-- 
-Clint

---

## #63679 — Larry Garfield — 2012-10-28T02:38:34+00:00

URL: https://externals.io/message/63640#63679 · In reply to: #63640

> I'm opening up several new threads to get discussion going on the 
> remaining "being debated" categories referenced in this 1.1 -> 1.2 
> change spec:
> https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented/change-requests 
>
>
> ------------------------------------------------------------------------
> Some people are in favor of the internal functions being generated by 
> an accessor declaration should be invisible and non-callable directly. 
> Others are in favor of leaving them visible and callable.
>
> *Type 1 ( Userland Programmer )**
> *
> As a userland programmer, someone who cares nothing for "how" php 
> works, only how their own code works. If they define an accessor they 
> expect to see an accessor, reflection should reflect that there are 
> accessors and no other "methods" they did not explicitly define. If 
> they were to reflect on all of the methods of their class and see a 
> number of __getHours() they may be confused as to why or where this 
> function came from. From their perspective, they have defined an 
> accessor and "how" that accessor works on the inside is of no 
> importance to them and only seeks to complicate or confuse matters 
> when they are exposed to these "implementation details" of the php 
> language its-self. If you tried to set a value such as $obj?abc = 1 
> through an accessor which could not be set, you would probably want to 
> see an error like: Warning, cannot set Class?abc, no setter defined.
>
> *Type 2 ( Internals Programmer )**
> *
> As an internals programmer, you want nothing hidden from you. If an 
> accessor implements special __getHours() methods to work its magic, 
> then you want to see them, you want to call them directly if you so 
> choose. In effect you want nothing hidden from you. In this case you 
> probably don't even want Reflection to reflect accessors as anything 
> different than specially formatted and called methods on the class. 
> This can be understandable because you want all information available 
> to you. You would probably not be confused if you wrote $obj?abc = 1 
> and got back an error like "Fatal Error: Class->__setAbc() function 
> does not exist.
>
> *Unfortunately 80 to 95% of all people who use PHP are of the first 
> type.**
> *
> Revealing these internal matters to them would only leave them 
> confused, possibly frustrated and likely asking about it to the 
> internals mailing list to answer (repeatedly).
> ------------------------------------------------------------------------
>
> Thoughts?
>

Speaking as a user-land programmer that's been following this thread, 
but hasn't been able to jump in yet due to the high volume of comments...

What's unclear to me is what my mental model should be for this new 
syntax.  That's important for informing how it should be exposed to me.

1) Should I have a mental model of this being some syntax candy on top 
of existing properties?  Vis, this is just a short-hand for bean-style 
classes?  By Bean style, I mean Properties that would be public but 
aren't because Public Is Bad(tm), so instead we have getX()/setX() for 
every property, so that we can still use the object like a struct rather 
than an object but still say we're using methods even though we've just 
reimplemented public properties with more verbose syntax.  (Note: Yes, I 
know that's a rather harsh and judgmental description.  I happen to 
firmly dislike Bean-style objects.)

2) Should I have a mental model that these fancy-pants properties are 
some different third thingie on objects, distinct from traditional data 
members and methods?

Right now I'm not sure which mental model I'm supposed to use, and I get 
the sense that there's no clear consensus on that question yet. That, I 
think, is the key question, and will inform how things like Reflection 
should expose data about this new syntax.

For instance, if model 2 is how I'm supposed to be thinking, then I'd 
expect I'd need a third reflection object for getting things off of an 
object/class, separate from traditional data members and methods.  Then 
it's consistently a third thingie.  If, however, I'm supposed to think 
of it as just a short-hand syntax for writing a bean, then I'd expect it 
to be presented to me as if I'd hand-written all of the stuff that this 
syntax is emulating.  Vis, methods show up as methods, and anything I'd 
be able to read/write directly without going through an intermediary 
method should show up as a property just as it does now.

Note: I'm speaking here of the mental model of the user, which does not 
necessarily have any relationship to the implementation details.  If I'm 
"supposed" to think of it as a third thingie, it doesn't matter that it 
may be implemented internally as syntactic sugar.  It should be 
presented to me as a third thingie, consistently, with the engine 
internal implementation details completely irrelevant.  (Which means 
they can be changed later if needs be.)

I don't know which mental model is intended, nor which one would be 
better, but that is, I believe, the question that should inform the rest 
of these discussions.

--Larry Garfield

---

## #63681 — Larry Garfield — 2012-10-28T02:48:12+00:00

URL: https://externals.io/message/63640#63681 · In reply to: #63679

> 
> > […]
>
> Speaking as a user-land programmer that's been following this thread, 
> but hasn't been able to jump in yet due to the high volume of comments...
>
> What's unclear to me is what my mental model should be for this new 
> syntax.  That's important for informing how it should be exposed to me.
>
> 1) Should I have a mental model of this being some syntax candy on top 
> of existing properties?  Vis, this is just a short-hand for bean-style 
> classes?  By Bean style, I mean Properties that would be public but 
> aren't because Public Is Bad(tm), so instead we have getX()/setX() for 
> every property, so that we can still use the object like a struct 
> rather than an object but still say we're using methods even though 
> we've just reimplemented public properties with more verbose syntax.  
> (Note: Yes, I know that's a rather harsh and judgmental description.  
> I happen to firmly dislike Bean-style objects.)
>
> 2) Should I have a mental model that these fancy-pants properties are 
> some different third thingie on objects, distinct from traditional 
> data members and methods?
>
> Right now I'm not sure which mental model I'm supposed to use, and I 
> get the sense that there's no clear consensus on that question yet. 
> That, I think, is the key question, and will inform how things like 
> Reflection should expose data about this new syntax.
>
> For instance, if model 2 is how I'm supposed to be thinking, then I'd 
> expect I'd need a third reflection object for getting things off of an 
> object/class, separate from traditional data members and methods.  
> Then it's consistently a third thingie.  If, however, I'm supposed to 
> think of it as just a short-hand syntax for writing a bean, then I'd 
> expect it to be presented to me as if I'd hand-written all of the 
> stuff that this syntax is emulating.  Vis, methods show up as methods, 
> and anything I'd be able to read/write directly without going through 
> an intermediary method should show up as a property just as it does now.
>
> Note: I'm speaking here of the mental model of the user, which does 
> not necessarily have any relationship to the implementation details.  
> If I'm "supposed" to think of it as a third thingie, it doesn't matter 
> that it may be implemented internally as syntactic sugar.  It should 
> be presented to me as a third thingie, consistently, with the engine 
> internal implementation details completely irrelevant.  (Which means 
> they can be changed later if needs be.)
>
> I don't know which mental model is intended, nor which one would be 
> better, but that is, I believe, the question that should inform the 
> rest of these discussions.
>
> --Larry Garfield

Addendum: If model 2 (third distinct thingie) is how I'm supposed to be 
thinking of them, then perhaps an additional keyword is needed to help 
drive that point home.  Vis:

class Foo {
   // Data member, directly accessible.
   public $bar;

   // Clearly a different type of thingie than $bar.
   public property $baz {
     get() { return $this->baz; }
     set($value) { $this->baz = $value;}
   }

   // A method as we know and love them.
   public function beep() {}

}

Of course, that should only be used if the mental model is that they're 
a distinct thingie.  If it's just syntactic sugar (again, mental model, 
not implementation), then a new keyword is a bad idea.

--Larry Garfield

---

## #63683 — Clint Priest — 2012-10-28T03:59:59+00:00

URL: https://externals.io/message/63640#63683 · In reply to: #63681

Hey Larry,

Glad you chimed in here on this.  I my opinion (author of thingy), they 
are separate and distinct from data members.  More specifically they 
are getter and setter code that is called when the property is accessed.

Using your example:

echo $obj->baz; // executes the code "return $this->baz;"

and

$obj->baz = 4;  // executes the code "$this->baz = $value;"

So from the perspective of the user of the class, they are just 
"properties" but internal to the class they are implemented with 
methods and code.

I think everyone would agree that your #1 is definitely not right, 
however I believe there is not consensus on whether or not these *are* 
different from properties.  To the consumer of the class, they are no 
different than properties, to the author of the class they are very 
different.


> 
> > […]
>
> Addendum: If model 2 (third distinct thingie) is how I'm supposed to
> be thinking of them, then perhaps an additional keyword is needed to
> help drive that point home.  Vis:
>
> class Foo {
>   // Data member, directly accessible.
>   public $bar;
>
>   // Clearly a different type of thingie than $bar.
>   public property $baz {
>     get() { return $this->baz; }
>     set($value) { $this->baz = $value;}
>   }
>
>   // A method as we know and love them.
>   public function beep() {}
>
> }
>
> Of course, that should only be used if the mental model is that
> they're a distinct thingie.  If it's just syntactic sugar (again,
> mental model, not implementation), then a new keyword is a bad idea.
>
> --Larry Garfield
>

--
-Clint

---

## #63684 — Stas Malyshev — 2012-10-28T06:47:43+00:00

URL: https://externals.io/message/63640#63684 · In reply to: #63677

Hi!

> 1) Currently __get() is only checked/invoked if there is not a property 
> already defined; ie properties shadow __get() (no performance penalty)

Yes, that's kind of the point of it - extending __get.

> 2) It would dramatically reduce performance because every property 
> access would have to create the function string, get it's hash value and 
> do a hash look up against the function table, just to see if there is a 

Not really, as we have property_info structure where we could record the
existence of such functions and we check property_info anyway AFAIR.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63685 — Stas Malyshev — 2012-10-28T07:04:54+00:00

URL: https://externals.io/message/63640#63685 · In reply to: #63678

Hi!

> Stas, you should probably do some research before posting such non-sense:

Which part is "non-sense"? I've brought you examples of Python and Ruby
not doing exactly what you claim all languages are doing. By your
definition, they don't have accessors - as you define accessors as
hidden methods that are uncallable and unavailable and not defined as
regular methods. In both Ruby and Python they are callable and defined
as regular (or regular with some special attributes) method.

I've brought you examples of popular languages that don't have this
feature at all - Java and standard C++ don't have it. I was wrong on
Javascript - though in Javascript, functions work differently from PHP
so there's no real relation to the current discussion.

> By accessors I am simply referring to getters, setters (and in the case 
> of php, issetter and unsetter).

I wish it was so, but it was mentioned many times in this discussion
that "accessors should be accessors" and that only the situation where
accessors are special functions that are not defined as regular methods,
are not callable and are hidden from reflection, etc. is the situation
where "accessors are accessors". This is not the case in Python, Ruby,
MS C++, D and Delphi by your own link - in all these cases, the
properties are defined as regular methods (possibly with some special
salt added) and no special effort is taken to hide them from any of the
language facilities and make them not callable.
Of course, there are also examples of languages going the other way -
namely, C#, F# and VB - but by no means the claim that I would be hard
pressed to find example of the languages which do not implement your
notion of "accessors being accessors" is true. For most dynamic
languages, the concept of "accessors being accessors" - hidden,
non-callable pseudo-methods - is a foreign concept.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #63686 — Patrick Schaaf — 2012-10-28T07:15:43+00:00

URL: https://externals.io/message/63640#63686 · In reply to: #63677

Am 28.10.2012 02:42 schrieb "Clint Priest" <cpriest@zerocue.com>:
>
> Sounds like you're implying that the mere existence of a properly named
function such as __prop_get_hours() would cause it to be called instead of
returning the property.

Only when the property does not exist, just like it is with __get

> 1) Currently __get() is only checked/invoked if there is not a property
already defined; ie properties shadow __get() (no performance penalty)

Right. I would expect / hope for __prop_get_XXX to work exactly the same.

> 2) It would dramatically reduce performance because every property access
would have to create the function string, get it's hash value and .....

But that only applies to an "accessor shadows property" doctrine, and that
is one of these complications / complexity issues which makes me  prefer
the "property exists means it's definite" doctrine as already deployed with
__get.

best regards
  Patrick

---

## #63690 — Lester Caine — 2012-10-28T11:40:08+00:00

URL: https://externals.io/message/63640#63690 · In reply to: #63685

Stas Malyshev wrote:
> > […]
> I wish it was so, but it was mentioned many times in this discussion
> that "accessors should be accessors" and that only the situation where
> accessors are special functions that are not defined as regular methods,
> are not callable and are hidden from reflection, etc. is the situation
> where "accessors are accessors". This is not the case in Python, Ruby,
> MS C++, D and Delphi by your own link - in all these cases, the
> properties are defined as regular methods (possibly with some special
> salt added) and no special effort is taken to hide them from any of the
> language facilities and make them not callable.

While I will probably be shouted down again ... can we clarify WHAT people are 
trying to achieve here?

__get and __set simply provide a crude means of using '$data' array to store 
properties in an object without having to define and load them every time. It 
has very limited use and in my own opinion is simply wrong anyway. But people 
seem to like to use it rather than simply defining their own $data array and 
accessing it directly? The reason it does not work for me is that I populate the 
data array ( in my case $mInfo ) directly from the persistent data in a 
database, and __get and __set simply do not work with this so never get used.

I can SEE the logic behind a get and set arrangement being 'formalised', and 
mirroring __get and __set is obviously necessary, but part of the reason for 
this discussion was - I thought - a way of allowing get/set to manage access to 
internal data that may not be a simple mirror, but rather calculated from other 
internal data ( hours based on second count )? 'Internal Accessor Method 
Visibility' needs to provide the user with information on how a returned value 
was generated? Even if that is only via documentation? Debugging that the 
process is working is the thing that gets difficult if you can 'see' the process.

The discussion has been 'split up', but I see 'Extra shorthand declaration' as 
another hiding of visibility such that 'public DateTime $date;' completely 
bypasses setting up the DateTime object and that $date will have it's own 
'accessors' or rather methods for accessing and configuring the object and it's 
values!

PHP has something no other language has - 'very flexible arrays' - and we can 
manage and pass data very nicely using these properly. Pass by reference allows 
complex data to be passed and massaged in a way that 'accessors' simply can't 
provide, and it's this method of working that we should be promoting rather than 
trying to hide things 'because the user does not need to know about them'. 
Everything used to be nicely visible in PHP, but that is becoming less the case 
and getting back to a framework where the IDE can provide all of the 'eye-candy' 
that is not needed when simply running the scripts should be considered as well?

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

Next page: https://externals.io/message/63640.md?page=2
