Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
Thanks!
Andrea Faulds
http://ajf.me/
Hey:
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
Thanks!
Hey:
-1 on this.
Actually, your example for explaining usage..
I don't see why it is must, add a getSize() will also meet the
needs, and more beatiful, as you can change $size to another name if
you like later.
thanks
--
Andrea Faulds
http://ajf.me/--
--
Xinchen Hui
@Laruence
http://www.laruence.com/
Hi
2014-10-24 5:02 GMT+02:00 Xinchen Hui laruence@php.net:
Hey:
-1 on this.
Actually, your example for explaining usage..
I don't see why it is must, add a getSize() will also meet the
needs, and more beatiful, as you can change $size to another name if
you like later.
I disagree on your disagreement, while it is not a must, it does not
make much sense that we are gonna call what essential is a function to
return a value that is not changed in anyway during that call. It does
not really perform a function, other than returning a value in 99% of
all cases, and therefore it makes perfect sense to allow readonly
properties in my mind.
It does not really make the code beautiful to prefix it with 'get' and
suffix it with '()' when you want such a value, it makes it
consistent, yes, but else it is just bloat to my eyes.
Internally it should also be a slightly be faster to not having to
call a method everytime as well, a program that does, lets say 50-100
calls to 'getX()' that can skip INIT_METHOD_CALL + DO_FCALL_BY_NAME
and instead just a FETCH_OBJ_R which is what should be after the
fcall, micro optimization I know (been a while since I went into these
parts so I might be a bit off though).
I'm a huge +1 on this, good job Andrea!
--
regards,
Kalle Sommer Nielsen
kalle@php.net
Hi
2014-10-24 5:02 GMT+02:00 Xinchen Hui laruence@php.net:
Hey:
-1 on this.
Actually, your example for explaining usage..
I don't see why it is must, add a getSize() will also meet the
needs, and more beatiful, as you can change $size to another name if
you like later.I disagree on your disagreement, while it is not a must, it does not
make much sense that we are gonna call what essential is a function to
return a value that is not changed in anyway during that call. It does
not really perform a function, other than returning a value in 99% of
all cases, and therefore it makes perfect sense to allow readonly
properties in my mind.It does not really make the code beautiful to prefix it with 'get' and
suffix it with '()' when you want such a value, it makes it
consistent, yes, but else it is just bloat to my eyes.
so you prefer to expose the name of the property anywhere?
let's say you expose a readonly int value name iSize..
but later, the value also need to be a double,
then you also prefer add another dval? (since you can not simple
change ival name, since it was exposed)
Internally it should also be a slightly be faster to not having to
call a method everytime as well, a program that does, lets say 50-100
calls to 'getX()' that can skip INIT_METHOD_CALL + DO_FCALL_BY_NAME
and instead just a FETCH_OBJ_R which is what should be after the
fcall, micro optimization I know (been a while since I went into these
parts so I might be a bit off though).
I knew this of course, but this is actually not related to this
specific "readonly" RFC
but if you are strict to this., then I'd like to say, this will
slowdown all FETCH_OBJ_R a bit, since this will need introduce a
condition to check whether a property is readonly.. only faster a
narrow case...
thanks
I'm a huge +1 on this, good job Andrea!
--
regards,Kalle Sommer Nielsen
kalle@php.net
--
Xinchen Hui
@Laruence
http://www.laruence.com/
so you prefer to expose the name of the property anywhere?
let's say you expose a readonly int value name iSize..
but later, the value also need to be a double,
then you also prefer add another dval? (since you can not simple
change ival name, since it was exposed)
Is that not already a problem with functions? You can't change their names. If you do change its name, you can add a __get.
I knew this of course, but this is actually not related to this
specific "readonly" RFCbut if you are strict to this., then I'd like to say, this will
slowdown all FETCH_OBJ_R a bit, since this will need introduce a
condition to check whether a property is readonly.. only faster a
narrow case...
Right, it will theoretically make public and protected property lookups ever-so-slightly slower. I'll need to benchmark it as I doubt it's a big deal in practice.
Though this could be worked around by making the write check be a different function. Or by inlining.
Andrea Faulds
http://ajf.me/
2014-10-24 7:09 GMT+02:00 Xinchen Hui laruence@php.net:
so you prefer to expose the name of the property anywhere?
let's say you expose a readonly int value name iSize..
but later, the value also need to be a double,
then you also prefer add another dval? (since you can not simple
change ival name, since it was exposed)
That is purely a naming decision, not something that should cause the
actual design of a language to not be available and even then, what
you are saying seems like a very edge case to me and I have a hard
time trying to understand if as I understand it, is your argument
against this feature.
--
regards,
Kalle Sommer Nielsen
kalle@php.net
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties
that makes them readable and writeable from different scopes.Since I am a big proponent of including specification patches in new
RFCs, I have decided to put my money (or rather, time) where my mouth
is and I have actually written a specification patch before writing an
RFC. I would love to see this become the new standard for RFCs
affecting the language.If you are curious at all about the behaviour, I suggest perusing the
fairly comprehensive set of twelve tests included in the main patch to
php-src.Thanks!
Andrea Faulds
http://ajf.me/
If nothing else, I like that this brings userland objects another step closer to those defined in extensions, which frequently use readonly properties.
I note that UString advertises a ->length rather than a ->getLength, and I haven't seen anyone in that thread object to that design decision, so I don't really buy the "you should never need this" argument.
The additional keyword and potential performance impact are more concerning, and will need to be weighed carefully against the benefits.
Hi,
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
+1
I've always wanted this, it has never made sense to me to write
numerous lines of code just to make an already declared property
readable from outside a class. __get() has helped to some extent,
but it has its disadvantages.
Cheers,
Andrey.
Am 24.10.2014 01:36 schrieb "Andrea Faulds" ajf@ajf.me:
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
+1 for the general feature, I'd love to have that available.
I have an idea regarding the additional keyword, with a small implication
(improvement) to the functionality provided, but at the cost of being
slightly quirky :) The idea is:
public $foo as private;
public $bar as protected;
protected $baz as private;
where the "as X" gives the writability scope. This introduces no new
keywords, and is currently not valid syntax, as far as I can see.
best regards
Patrick
Am 24.10.2014 01:36 schrieb "Andrea Faulds" ajf@ajf.me:
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
+1 for the general feature, I'd love to have that available.
I have an idea regarding the additional keyword, with a small implication
(improvement) to the functionality provided, but at the cost of being
slightly quirky :) The idea is:public $foo as private;
public $bar as protected;
protected $baz as private;where the "as X" gives the writability scope. This introduces no new
keywords, and is currently not valid syntax, as far as I can see.
More as musing than anything else - might provide some insight via an analogy.
Properties and methods have a scope that is: private, protected or public.
This reminds me of the Unix: owner, group & other file permissions.
Unix allows: read, write & execute.
This RFC is trying to control how a property could be used with a readonly restriction.
Are there times when one would want to be able to set a property value - but not
read it ?
Thinking about execute - would there be any mileage in an execute permission -
could be useful for a property that had been assigned an anonymous function.
Finally we could bring it all together and sidestep the scoping keywords using
'var' instead. Thus:
var $callback as 0751;
Would define a property that contains an anonymous function that could be called
by anyone, inspected by the class & related class, but only set by the class itself!
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
Hi,
Am 24.10.2014 01:36 schrieb "Andrea Faulds" ajf@ajf.me:
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
+1 for the general feature, I'd love to have that available.
I have an idea regarding the additional keyword, with a small implication
(improvement) to the functionality provided, but at the cost of being
slightly quirky :) The idea is:public $foo as private;
public $bar as protected;
protected $baz as private;where the "as X" gives the writability scope. This introduces no new
keywords, and is currently not valid syntax, as far as I can see.More as musing than anything else - might provide some insight via an
analogy.Properties and methods have a scope that is: private, protected or public.
This reminds me of the Unix: owner, group & other file permissions.Unix allows: read, write & execute.
This RFC is trying to control how a property could be used with a readonly
restriction.
Are there times when one would want to be able to set a property value -
but not
read it ?Thinking about execute - would there be any mileage in an execute
permission -
could be useful for a property that had been assigned an anonymous
function.Finally we could bring it all together and sidestep the scoping keywords
using
'var' instead. Thus:var $callback as 0751;
Would define a property that contains an anonymous function that could be
called
by anyone, inspected by the class & related class, but only set by the
class itself!
To follow up on this, and to give more readable code, we could also use
this:
var $callback as rwxrw---x;
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT
Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information:
http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h>--
Regards,
--
Florian Margaine
Finally we could bring it all together and sidestep the scoping keywords
using
'var' instead. Thus:var $callback as 0751;
Would define a property that contains an anonymous function that could be
called
by anyone, inspected by the class & related class, but only set by the
class itself!To follow up on this, and to give more readable code, we could also use
this:var $callback as rwxrw---x;
+1, although that would have been:
var $callback as rwxr-x--x;
Again musing further:
var $callback as rwsr-x--x;
A callback that when executed/called would have 'private' access permissions on properties!
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties
that makes them readable and writeable from different scopes.Since I am a big proponent of including specification patches in new
RFCs, I have decided to put my money (or rather, time) where my mouth
is and I have actually written a specification patch before writing
an RFC. I would love to see this become the new standard for RFCs
affecting the language.
Thanks for the work (again). It's an interesting small idea but I'd much
prefer revisiting the original getter/setter RFC [1] which had a
majority but just fell short of the 66% mark.
This RFC only implements parts of the getter/setter functionality
(readonly properties) but it does not address the fact that sometimes
you want to add logic to a setter or a getter and if you don't have
language level getters/setters you end up having to change the interface
of the object from a public property to a getFoo/setFoo pair.
This leads to everyone having getFoo/setFoo by default just to avoid
interface changes or mixed interfaces of public properties and setFoo.
[1] https://wiki.php.net/rfc/propertygetsetsyntax-v1.2
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
Thanks for the work (again). It's an interesting small idea but I'd much prefer revisiting the original getter/setter RFC [1] which had a majority but just fell short of the 66% mark.
This RFC only implements parts of the getter/setter functionality (readonly properties) but it does not address the fact that sometimes you want to add logic to a setter or a getter and if you don't have language level getters/setters you end up having to change the interface of the object from a public property to a getFoo/setFoo pair.
This leads to everyone having getFoo/setFoo by default just to avoid interface changes or mixed interfaces of public properties and setFoo.
As much i really like the idea to have better properties management in
PHP I see this RFC as an attempt to solve only part of the problem
while dropping most of the other ideas implemented in the past RFCs.
My take on that is that some will vote no, or won't like the idea of
adding anything in this area. Making compromises and implement partial
solutions will only delay the implementation of the complete solution.Many of us agree that __get/__set is a pain to deal with.The need of
readonly, writeonly or properties with some logic to define or get a
value is a lond due need. Many other languages support that out of the
box since long already. Past RFCs, like the c# one, proposed that. I
would rather focus on trying to find an acceptable syntax and
implementation instead of doing baby steps like that. Baby steps work
very well for scalar type hinting, solving one issue after another,
etc. But for properties we are at the risk of hainvg a serie of
separate RFCs solving the properties management problems in different
ways bringing even more troubles and inconsistencies.
I think I might be misunderstood, here. While getters and setters can do this, and I’m very much in favour of also reviving a simplified version of the getter/setter RFC (previous one was way too complex), I don’t see this as partly implementing them/baby steps/etc. I fact, I think readonly properties could work together with getters/setters.
I don't like using property getters and setters to control whether a property can be written to or read from. I think they're the wrong solution for that - why have a virtual property with boilerplate restricted visibility accessors and mutators that get/set a hidden private property, with their associated performance penalties, when you can just make a real property that can't be read by outsiders?
I think getters and setters are useful and I probably will try to revive them too sometime soon, but I think they’re actually the wrong tool for this specific job.
--
Andrea Faulds
http://ajf.me/
Thanks for the work (again). It's an interesting small idea but I'd much prefer revisiting the original getter/setter RFC [1] which had a majority but just fell short of the 66% mark.
This RFC only implements parts of the getter/setter functionality (readonly properties) but it does not address the fact that sometimes you want to add logic to a setter or a getter and if you don't have language level getters/setters you end up having to change the interface of the object from a public property to a getFoo/setFoo pair.
This leads to everyone having getFoo/setFoo by default just to avoid interface changes or mixed interfaces of public properties and setFoo.
As much i really like the idea to have better properties management in
PHP I see this RFC as an attempt to solve only part of the problem
while dropping most of the other ideas implemented in the past RFCs.
My take on that is that some will vote no, or won't like the idea of
adding anything in this area. Making compromises and implement partial
solutions will only delay the implementation of the complete solution.Many of us agree that __get/__set is a pain to deal with.The need of
readonly, writeonly or properties with some logic to define or get a
value is a lond due need. Many other languages support that out of the
box since long already. Past RFCs, like the c# one, proposed that. I
would rather focus on trying to find an acceptable syntax and
implementation instead of doing baby steps like that. Baby steps work
very well for scalar type hinting, solving one issue after another,
etc. But for properties we are at the risk of hainvg a serie of
separate RFCs solving the properties management problems in different
ways bringing even more troubles and inconsistencies.I think I might be misunderstood, here. While getters and setters can
do this, and I’m very much in favour of also reviving a simplified
version of the getter/setter RFC (previous one was way too complex),
I don’t see this as partly implementing them/baby steps/etc. I fact,
I think readonly properties could work together with
getters/setters.
Fair enough, thanks for the clarification. It also sounds good to have
very simple getter/setters when needed and simple properties +
eventually readonly otherwise. issetters/unsetters aren't extremely needed.
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
hi Andrea,
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
As much i really like the idea to have better properties management in
PHP I see this RFC as an attempt to solve only part of the problem
while dropping most of the other ideas implemented in the past RFCs.
My take on that is that some will vote no, or won't like the idea of
adding anything in this area. Making compromises and implement partial
solutions will only delay the implementation of the complete solution.
Many of us agree that __get/__set is a pain to deal with.The need of
readonly, writeonly or properties with some logic to define or get a
value is a lond due need. Many other languages support that out of the
box since long already. Past RFCs, like the c# one, proposed that. I
would rather focus on trying to find an acceptable syntax and
implementation instead of doing baby steps like that. Baby steps work
very well for scalar type hinting, solving one issue after another,
etc. But for properties we are at the risk of hainvg a serie of
separate RFCs solving the properties management problems in different
ways bringing even more troubles and inconsistencies.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
Hi,
hi Andrea,
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
As much i really like the idea to have better properties management in
PHP I see this RFC as an attempt to solve only part of the problem
while dropping most of the other ideas implemented in the past RFCs.
My take on that is that some will vote no, or won't like the idea of
adding anything in this area. Making compromises and implement partial
solutions will only delay the implementation of the complete solution.Many of us agree that __get/__set is a pain to deal with.The need of
readonly, writeonly or properties with some logic to define or get a
value is a lond due need. Many other languages support that out of the
box since long already. Past RFCs, like the c# one, proposed that. I
would rather focus on trying to find an acceptable syntax and
implementation instead of doing baby steps like that. Baby steps work
very well for scalar type hinting, solving one issue after another,
etc. But for properties we are at the risk of hainvg a serie of
separate RFCs solving the properties management problems in different
ways bringing even more troubles and inconsistencies.
Pierre, I rarely disagree with you, but this is one such case.
It is true that we can look at this as a partial solution to a bigger
problem, or as you said - a baby step. However, I see this as the
perfect solution for a very narrow, yet also a very common problem,
and I don't see it blocking a more abstract solution in the future.
From a userland POV, it is simple, very effective and there's
practically no way to achieve the same goal with less amount of code.
In short - it's no panacea to all the limitations that we currently
have on property management, but it is still extremely useful for
implementing classes that only need to have getters.
On another note, I share Nikita's concern about using the "readonly"
keyword and I'd love that to be improved, but the best alternative I
could think of is "readable" and IMO it doesn't have a clearer
meaning.
Cheers,
Andrey.
Pierre, I rarely disagree with you, but this is one such case.
It is true that we can look at this as a partial solution to a bigger
problem, or as you said - a baby step. However, I see this as the
perfect solution for a very narrow, yet also a very common problem,
and I don't see it blocking a more abstract solution in the future.
That’s basically my thoughts on this RFC. I think it’s still quite useful even if it’s not as useful as it could be without certain other additions.
From a userland POV, it is simple, very effective and there's
practically no way to achieve the same goal with less amount of code.In short - it's no panacea to all the limitations that we currently
have on property management, but it is still extremely useful for
implementing classes that only need to have getters.
It’s also faster!
On another note, I share Nikita's concern about using the "readonly"
keyword and I'd love that to be improved, but the best alternative I
could think of is "readable" and IMO it doesn't have a clearer
meaning.
Yeah, that’s the problem. It is somewhat unclear, but any other keyword choice is even more confusing. I discussed this quite a bit in StackOverflow’s PHP chatroom (http://chat.stackoverflow.com/rooms/11/php) and couldn’t come up with anything better.
Also, as I note in the RFC, we already use readonly in the docs for some classes, and for C#-style only-set-once read-only properties, we could use final or immutable.
--
Andrea Faulds
http://ajf.me/
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that
makes them readable and writeable from different scopes.Since I am a big proponent of including specification patches in new RFCs,
I have decided to put my money (or rather, time) where my mouth is and I
have actually written a specification patch before writing an RFC. I would
love to see this become the new standard for RFCs affecting the language.If you are curious at all about the behaviour, I suggest perusing the
fairly comprehensive set of twelve tests included in the main patch to
php-src.Thanks!
While I think the functionality behind this proposal is nice in principle,
I have two objections with the RFC:
-
It uses the "readonly" modifier, to refer to a property that is publicly
readable, but protectedly writable (or protectedly readable and privately
writable). This isn't entirely obvious from the term "readonly" and also
does not match the behavior of other languages employing a "readonly"
modifier, like C#. An additional complication may be encountered in the
case where the readonly property stores an object, in which case I presume
it will be possible to modify the stored object ($obj->readonlyProp->prop =
42), which is likely not expected "readonly" behavior. -
If the aim of this RFC is to replace the getFoo() pattern with the use
of "readonly public $foo" properties, a primary difference will be that a
getFoo() method can be declared in an interface, whereas a "readonly public
$foo" property cannot be. Thus code making use of interfaces will not be
able to employ this feature. And I don't think that allowing properties in
interfaces is reasonable at this point, because the implementations will be
limited to simple-storage properties - only with more comprehensive
property accessor support would implementations be allowed to use more
complex backing code.
For these reasons I do not think this RFC is suitable for inclusion in PHP
in its current state. As others in this thread have already pointed out, it
may be advisable to reconsider readonly properties in the broader context
of property accessors.
Nikita
While I think the functionality behind this proposal is nice in principle, I have two objections with the RFC:
- It uses the "readonly" modifier, to refer to a property that is publicly readable, but protectedly writable (or protectedly readable and privately writable). This isn't entirely obvious from the term "readonly" and also does not match the behavior of other languages employing a "readonly" modifier, like C#. An additional complication may be encountered in the case where the readonly property stores an object, in which case I presume it will be possible to modify the stored object ($obj->readonlyProp->prop = 42), which is likely not expected "readonly" behavior.
It’s not the best name, I agree, but there isn’t a better name I could come up with in discussions. I don’t think the object thing is an issue, it’s not like there’s much we can do about that.
- If the aim of this RFC is to replace the getFoo() pattern with the use of "readonly public $foo" properties, a primary difference will be that a getFoo() method can be declared in an interface, whereas a "readonly public $foo" property cannot be. Thus code making use of interfaces will not be able to employ this feature. And I don't think that allowing properties in interfaces is reasonable at this point, because the implementations will be limited to simple-storage properties - only with more comprehensive property accessor support would implementations be allowed to use more complex backing code.
Right, interfaces currently can’t declare properties and I’m not going to change that in this RFC. If I revisit getters and setters, that would be changed. Still, I think there is usefulness to this without interfaces… it’s just more limited, sadly.
It would work quite well with getters and setters and interfaces, if later added. Within interfaces, readonly could be used to avoid compelling implementing classes to support writing:
interface Point {
public readonly $x, $y;
}
But without preventing implementing classes from supporting it.
Andrea Faulds
http://ajf.me/
- If the aim of this RFC is to replace the getFoo() pattern with the use of "readonly public $foo" properties, a primary difference will be that a getFoo() method can be declared in an interface, whereas a "readonly public $foo" property cannot be. Thus code making use of interfaces will not be able to employ this feature. And I don't think that allowing properties in interfaces is reasonable at this point, because the implementations will be limited to simple-storage properties - only with more comprehensive property accessor support would implementations be allowed to use more complex backing code.
Right, interfaces currently can’t declare properties and I’m not going to change that in this RFC. If I revisit getters and setters, that would be changed. Still, I think there is usefulness to this without interfaces… it’s just more limited, sadly.
It would work quite well with getters and setters and interfaces, if later added. Within interfaces, readonly could be used to avoid compelling implementing classes to support writing:
interface Point {
public readonly $x, $y;
}But without preventing implementing classes from supporting it.
I added a little Future Scope section on this: https://wiki.php.net/rfc/readonly_properties#puture_scope
--
Andrea Faulds
http://ajf.me/
Hi!
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
For me, this seems both too big and too small. Too small, because if you
really it assigns a keyword to special use case of a generic feature,
and thus I think does not lead us on the right path - we could not
assign keywords to every behavior of properties, so either we forever
reject the idea of having any generic solution there, or we'd eventually
have two solutions, working in two different ways.
Too big because this particular case is already very easy to implement
by just making the property protected and having a public getter. It
doesn't add any capability that we already don't have, and having a
keyword just to save typing () seems unnecessary to me (performance is
really irrelevant here, if your performance is bound by speed of
accessors, you should be writing that code in C).
Also, the name "readonly" appears misleading as it's not really read
only - it's only read only for some classes, but writeable for others.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that makes them readable and writeable from different scopes.
Since I am a big proponent of including specification patches in new RFCs, I have decided to put my money (or rather, time) where my mouth is and I have actually written a specification patch before writing an RFC. I would love to see this become the new standard for RFCs affecting the language.
If you are curious at all about the behaviour, I suggest perusing the fairly comprehensive set of twelve tests included in the main patch to php-src.
Thanks!
I just had a thought on both the naming and future-proofing concerns of
this proposal: what about pre-emptively reserving the skeleton of the
syntax needed for accessors, without actually implementing them?
For instance, one of the (confusingly many) syntaxes allowed by
https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 would have been this:
private $foo { public get; protected set; }
In that instance, this was seen as short-hand for the default "proxy
method", but the effect is to modify the visibility of the property
without any extra behaviour.
If we remove the requirement to specify both get and set if the guard
clause is added, we get a simple syntax that covers the two cases the
RFC's "readonly" keyword does, plus one more:
// Current RFC
public readonly $foo; // read public, write protected
protected readonly $foo; // read protected, write private
// With only "set" keyword
public $foo { protected set; }
protected $foo { private set; }
public $foo { private set; } // read public, write private
// With only "get" keyword
protected $foo { public get; }
private $foo { protected get; }
private $foo { public get; }
// With both keywords, since "var" has been undeprecated
var $foo { public get; protected set; }
var $foo { protected get; private set; }
var $foo { public get; private set; }
This syntax does imply other combinations like "private get; public
set;" (effectively "write-only" from certain scopes), which may
complicate matters somewhat. To keep things simple, we could simply
enforce a rule at compile time that "read visibility must not be more
restrictive than write visibility".
This gets rid of the ambiguity of the "readonly" keyword, and makes the
behaviour of "read protected, write private" much more obvious. It also
opens the door to syntax for accessors without placing much restriction
on how they could work...
// Forwards compatible to all these and more...
var $foo { public get { return $this->bar * 10; } private set; }
var $foo { public get() { return $this->bar * 10; } private set; }
var $foo { public get => $this->bar * 10; private set; }
var $foo { public get: existingMethod; private set; }
--
Rowan Collins
[IMSoP]
I just had a thought on both the naming and future-proofing concerns of this proposal: what about pre-emptively reserving the skeleton of the syntax needed for accessors, without actually implementing them?
I’ve been thinking about this. While public readonly $foo;
does work, it is confusing (only readonly to public) and limiting (no public/private option). Plus, while it could work with getters/setters, it’s hardly ideal.
On the other hand, while having C#-style syntax here gives us a full feature set, I don’t like that it inverts the order of a declaration. To show you what I mean, here’s a normal property:
public $foobar;
Now, here’s a property with C#-style syntax:
var $foobar { public get; private set; };
See how the public
moved to the right? I don’t like that, I want to avoid that if possible. I’m all for C#-style syntax with the get and set, but I don’t like that it moves the visibility specifier.
Similarly, I don’t like this either:
public $foobar { get; private set; }
Now the visibility is on both sides! Yuck. That’s the worst of both worlds.
What I’d like is probably something like this:
public/private $foobar;
Tentative syntax. But this way, the visibility stays on the left. I think that’s good for readability. If you omit the second specifier, then the first one applies to getting and setting, as now. If you include it, the first one applies to getting, the second one to setting.
It’d also be compatible with properties, too:
public/private $foobar {
get { return $this->bar * $this->foo; }
set($value) { $this->bar = $value / $this->foo; }
}
It doesn’t prevent truly read-only properties, either:
public $foobar {
get { return $this->bar * $this->foo; }
}
Does this sound like a good idea? A similar idea came up in the discussions 8 years ago on readonly.
--
Andrea Faulds
http://ajf.me/
Tentative syntax. But this way, the visibility stays on the left. I think that’s good for readability. If you omit the second specifier, then the first one applies to getting and setting, as now. If you include it, the first one applies to getting, the second one to setting.
It’d also be compatible with properties, too:
public/private $foobar { get { return $this->bar * $this->foo; } set($value) { $this->bar = $value / $this->foo; } }
It doesn’t prevent truly read-only properties, either:
public $foobar { get { return $this->bar * $this->foo; } }
Does this sound like a good idea? A similar idea came up in the discussions 8 years ago on readonly.
I like it, except for the fact that if you add a custom getter to a
property suddenly it becomes readonly unless you remember to add "; set"
to the end of the block, right?
How about this instead for readonly:
public $foobar {
get { return $this->bar * $this->foo; }; readonly
}
And if the flag isn't there, set is implicitly present.
That'd mean you also can keep "public readonly $foobar;" as a shorthand
for readonly properties without custom getter.
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
Tentative syntax. But this way, the visibility stays on the left. I think
that’s good for readability. If you omit the second specifier, then the
first one applies to getting and setting, as now. If you include it, the
first one applies to getting, the second one to setting.It’d also be compatible with properties, too:
public/private $foobar { get { return $this->bar * $this->foo; } set($value) { $this->bar = $value / $this->foo; } }
It doesn’t prevent truly read-only properties, either:
public $foobar { get { return $this->bar * $this->foo; } }
Does this sound like a good idea? A similar idea came up in the
discussions 8 years ago on readonly.I like it, except for the fact that if you add a custom getter to a property
suddenly it becomes readonly unless you remember to add "; set" to the end
of the block, right?How about this instead for readonly:
public $foobar { get { return $this->bar * $this->foo; }; readonly }
And if the flag isn't there, set is implicitly present.
That'd mean you also can keep "public readonly $foobar;" as a shorthand for
readonly properties without custom getter.
I like this idea.
Also confirmed what I was trying to say: While we can have many RFCs
covering the properties properties and behavior, having one covering
the needs in one go will allow us to be more consistent and developer
friendly.
--
Pierre
@pierrejoye | http://www.libgd.org
Jordi Boggiano wrote on 28/10/2014 07:17:
How about this instead for readonly:
public $foobar { get { return $this->bar * $this->foo; }; readonly }
And if the flag isn't there, set is implicitly present.
That'd mean you also can keep "public readonly $foobar;" as a
shorthand for readonly properties without custom getter.
I think it could be problematic to have too many variants of the syntax,
as it leads to more inconsistencies that people have to understand, and
more complex code needed in third-party parsers (IDEs, alternative
implementations, etc).
Keeping the "readonly" attribute also keeps the ambiguity of what it
actually means: immutable, protected, private? Sticking to the existing
visibility modifiers makes it more explicit what's actually being set.
--
Rowan Collins
[IMSoP]
I like it, except for the fact that if you add a custom getter to a property suddenly it becomes readonly unless you remember to add "; set" to the end of the block, right?
Well, no. If you choose to specify getters and setters, and only specify a setter, of course it is read-only. It doesn’t make sense to have a getter and no setter and yet expect a property to be writeable.
How about this instead for readonly:
public $foobar { get { return $this->bar * $this->foo; }; readonly }
And if the flag isn't there, set is implicitly present.
This is really confusing and I don’t think it’s a good idea.
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 28/10/2014 14:08:
I like it, except for the fact that if you add a custom getter to a property suddenly it becomes readonly unless you remember to add "; set" to the end of the block, right?
Well, no. If you choose to specify getters and setters, and only specify a setter, of course it is read-only. It doesn’t make sense to have a getter and no setter and yet expect a property to be writeable.
I think the problem is that the get and set annotations are serving
multiple purposes - to change the visibility, to define custom
accessor/mutator code, but also to declare whether certain actions are
possible at all. Since the default is for the property to be readable
and writable, the fact that adding "{ get; }" makes it readonly isn't
immediately intuitive, although it does makes sense once you think about it.
Andrea Faulds wrote on 28/10/2014 14:08:
I like it, except for the fact that if you add a custom getter to a property suddenly it becomes readonly unless you remember to add "; set" to the end of the block, right?
Well, no. If you choose to specify getters and setters, and only specify a setter, of course it is read-only. It doesn’t make sense to have a getter and no setter and yet expect a property to be writeable.I think the problem is that the get and set annotations are serving multiple purposes - to change the visibility, to define custom accessor/mutator code, but also to declare whether certain actions are possible at all. Since the default is for the property to be readable and writable, the fact that adding "{ get; }" makes it readonly isn't immediately intuitive, although it does makes sense once you think about it.
Hmm. Perhaps we need this, then:
public $foobar; // public read, private write
public/private $foobar; // public read, private write
public readonly $foobar; // public read, not writeable at all
This then confined set/get entirely to implementation details. A read-only property would be denoted by readonly.
With the last one, you can only have get, for the first two, you must have both get and set.
Does that work? Seems pretty good to me.
--
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 28/10/2014 14:08:
I like it, except for the fact that if you add a custom getter to a property suddenly it becomes readonly unless you remember to add "; set" to the end of the block, right?
Well, no. If you choose to specify getters and setters, and only specify a setter, of course it is read-only. It doesn’t make sense to have a getter and no setter and yet expect a property to be writeable.I think the problem is that the get and set annotations are serving multiple purposes - to change the visibility, to define custom accessor/mutator code, but also to declare whether certain actions are possible at all. Since the default is for the property to be readable and writable, the fact that adding "{ get; }" makes it readonly isn't immediately intuitive, although it does makes sense once you think about it.
Hmm. Perhaps we need this, then:
public $foobar; // public read, private write
public/private $foobar; // public read, private write
public readonly $foobar; // public read, not writeable at allThis then confined set/get entirely to implementation details. A read-only property would be denoted by readonly.
With the last one, you can only have get, for the first two, you must have both get and set.
Does that work? Seems pretty good to me.
Yup that's definitely better than having the readonly flag in the {}
block as I had it.
I'd however say that it should be possible to define a writable property
with only a getter and then the setter would implicitly be created.
Since readonly is the way to define writability why should I have to
specify a setter (even a default empty one) if none is needed?
P.S: Don't want to open pandora's box, but we could also have writeonly
for completeness perhaps. I don't really see the use case at all though
(immutability sure, mutant bottomless pit objects not so much:).
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
Yup that's definitely better than having the readonly flag in the {} block as I had it.
I'd however say that it should be possible to define a writable property with only a getter and then the setter would implicitly be created. Since readonly is the way to define writability why should I have to specify a setter (even a default empty one) if none is needed?
P.S: Don't want to open pandora's box, but we could also have writeonly for completeness perhaps. I don't really see the use case at all though (immutability sure, mutant bottomless pit objects not so much:).
I don’t think allowing write-only properties is a good idea if we need a new keyword for it.
To be honest, for such a use case, using a setter method is probably better than assigning as if it were a normal property. While people would probably tolerate and understand read-only (from their perspective outside the class) properties, I think write-only properties will just lead to poor API design and confusion.
Andrea Faulds
http://ajf.me/
I just had a thought on both the naming and future-proofing concerns of
this proposal: what about pre-emptively reserving the skeleton of the
syntax needed for accessors, without actually implementing them?I’ve been thinking about this. While
public readonly $foo;
does work, it
is confusing (only readonly to public) and limiting (no public/private
option). Plus, while it could work with getters/setters, it’s hardly ideal.On the other hand, while having C#-style syntax here gives us a full
feature set, I don’t like that it inverts the order of a declaration. To
show you what I mean, here’s a normal property:public $foobar;
Now, here’s a property with C#-style syntax:
var $foobar { public get; private set; };
See how the
public
moved to the right? I don’t like that, I want to
avoid that if possible. I’m all for C#-style syntax with the get and set,
but I don’t like that it moves the visibility specifier.Similarly, I don’t like this either:
public $foobar { get; private set; }
Now the visibility is on both sides! Yuck. That’s the worst of both worlds.
What I’d like is probably something like this:
public/private $foobar;
Tentative syntax. But this way, the visibility stays on the left. I think
that’s good for readability. If you omit the second specifier, then the
first one applies to getting and setting, as now. If you include it, the
first one applies to getting, the second one to setting.It’d also be compatible with properties, too:
public/private $foobar { get { return $this->bar * $this->foo; } set($value) { $this->bar = $value / $this->foo; } }
Sorry, but I don't like this. This means that the visibility modifier is no
longer next to the thing that it applies to, IMO this is actually harmful
to the readability because the order in which the accessors were defined
then becomes significant so you have to either look at the ordering or have
the parser enforce a particular order, plus "public/private" looks
syntactically weird.
I would suggest something like this:
public $foobar {
get { return $this->bar * $this->foo; }
private set($value) { $this->bar = $value / $this->foo }
}
...where only a single visibility modifier is permitted on the left, and
this is treated as the default visibility for the accessors, which are
free to declare another visibility if they want - so the following would be
equivalent:
public $foobar {
public get { return $this->bar * $this->foo; }
private set($value) { $this->bar = $value / $this->foo }
}
Another bonus here is that the var keyword can still be permitted on the
left for those who prefer the C# syntax, as a synonym of public (i.e. the
current behaviour of var).
It doesn’t prevent truly read-only properties, either:
public $foobar { get { return $this->bar * $this->foo; } }
Does this sound like a good idea? A similar idea came up in the
discussions 8 years ago on readonly.--
Andrea Faulds
http://ajf.me/
Chris Wright wrote on 28/10/2014 09:46:
I would suggest something like this:
public $foobar {
get { return $this->bar * $this->foo; }
private set($value) { $this->bar = $value / $this->foo }
}...where only a single visibility modifier is permitted on the left,
and this is treated as the default visibility for the accessors,
which are free to declare another visibility if they want - so the
following would be equivalent:public $foobar {
public get { return $this->bar * $this->foo; }
private set($value) { $this->bar = $value / $this->foo }
}
The reason I opted for using var rather than having modifiers on both
sides was because I wasn't sure what should be done with expressions
like this:
public $foo { private get; private set; }
Is that allowed, and actually creates a private property? Or does the
compiler detect it and give some kind of error? It feels like a bug in
the syntax that the same information is included in more than one place,
meaning it can express contradictions.
--
Rowan Collins
[IMSoP]
Sorry, but I don't like this. This means that the visibility modifier is no longer next to the thing that it applies to,
I wouldn’t say that. The visibility modifier is an aspect of the property itself, not its implementation. A property can be public-readable and private-writeable regardless of whether it’s a plain property or is a getter and a setter.
IMO this is actually harmful to the readability because the order in which the accessors were defined then becomes significant
It wouldn’t be significant. The public/private doesn’t apply to the getters and setters, it applies to reading and writing from the property, regardless of its implementation.
If we did’t enforce order, got the read/write syntax and getters and setters, hypothetically this would be possible:
public/private $foobar {
set($value) { … }
get { … }
}
However, hopefully coding style guides would discourage that.
I would suggest something like this:
public $foobar {
get { return $this->bar * $this->foo; }
private set($value) { $this->bar = $value / $this->foo }
}...where only a single visibility modifier is permitted on the left, and this is treated as the default visibility for the accessors, which are free to declare another visibility if they want
I don’t like this, it’s moving the visibility again and having it split between the start and end of the declaration.
Andrea Faulds
http://ajf.me/
Hi Andrea,
I don't have strong opinion about this proposal.
It doesn't make any harm to the engine, and it really may speed-up code
especially written for read-only properties.
On the other hand you introduce new orthogonal to private/protected/public
visibility rule,
and I'm not sure if this complication is good for language.
Why did you disable read-only static methods? (I just didn't get it).
Thanks. Dmitry.
Good evening once again,
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
It proposes, with a working implementation, a modifier for properties that
makes them readable and writeable from different scopes.Since I am a big proponent of including specification patches in new RFCs,
I have decided to put my money (or rather, time) where my mouth is and I
have actually written a specification patch before writing an RFC. I would
love to see this become the new standard for RFCs affecting the language.If you are curious at all about the behaviour, I suggest perusing the
fairly comprehensive set of twelve tests included in the main patch to
php-src.Thanks!
Andrea Faulds
http://ajf.me/
Hi Andrea,
I don't have strong opinion about this proposal.
It doesn't make any harm to the engine, and it really may speed-up code especially written for read-only properties.
On the other hand you introduce new orthogonal to private/protected/public visibility rule,
and I'm not sure if this complication is good for language.Why did you disable read-only static methods? (I just didn't get it).
You couldn't really have a read-only method, there's no get/set equivalent for methods. The reason they're explicitly disallowed in the code is because, to avoid shift/reduce conflicts, I have to add it as a member modifier but then check the AST to see if it was used.
The reason for disallowing static methods is we currently don't use separate code paths for get/set of static methods, we just call one function to obtain a pointer. Of course I could make that function be told whether it's for writing, I just hadn't done it yet.
--
Andrea Faulds
http://ajf.me/
Hi Andrea,
I don't have strong opinion about this proposal.
It doesn't make any harm to the engine, and it really may speed-up code
especially written for read-only properties.
On the other hand you introduce new orthogonal to
private/protected/public visibility rule,
and I'm not sure if this complication is good for language.Why did you disable read-only static methods? (I just didn't get it).
You couldn't really have a read-only method, there's no get/set equivalent
for methods. The reason they're explicitly disallowed in the code is
because, to avoid shift/reduce conflicts, I have to add it as a member
modifier but then check the AST to see if it was used.The reason for disallowing static methods is we currently don't use
separate code paths for get/set of static methods, we just call one
function to obtain a pointer. Of course I could make that function be told
whether it's for writing, I just hadn't done it yet.
Oh. I meant static properties, of course. (zend_compile.c line 4219)
Thanks. Dmitry.
--
Andrea Faulds
http://ajf.me/
Oh. I meant static properties, of course. (zend_compile.c line 4219)
So did I in the second paragraph. Static property get and set currently goes through the same function… but really the reason they’re disallowed is me not getting round to implementing them yet.
--
Andrea Faulds
http://ajf.me/
if there are no conceptual and implantation problems with static readonly
properties, it's better to implement them in the same patch.
Oh. I meant static properties, of course. (zend_compile.c line 4219)
So did I in the second paragraph. Static property get and set currently
goes through the same function… but really the reason they’re disallowed is
me not getting round to implementing them yet.--
Andrea Faulds
http://ajf.me/
Here’s another RFC: https://wiki.php.net/rfc/readonly_properties
After further though, I am withdrawing this RFC. It’s confusing and a half-baked solution to the problem. Also, I’m not sure I like the idea of variable visibility accessors in any other form, either. So that’s that.
--
Andrea Faulds
http://ajf.me/