I had thought of a deviation on some of the ideas presented to get rid of read-only/write-only while still keeping the ability to maintain their effect, if we so decide that the feature is wanted. Here it is:
class TimePeriod {
private $Seconds;
public $Hours {
get() { return $this->Hours; }
final set NULL;
}
}
It's close to what's been suggested but is pretty clear that there IS NO SETTER it could not be called within the class and since its final it cannot be over-ridden. I've included this in the change tracking document.
Thoughts?
-Clint
read-only => final set null;
It begins to be verbose.
As I said many times, why don't you want to use the "const" keyword? It
already exists and is pretty well understood by everybody.
2012/10/20 Clint Priest cpriest@zerocue.com
I had thought of a deviation on some of the ideas presented to get rid of
read-only/write-only while still keeping the ability to maintain their
effect, if we so decide that the feature is wanted. Here it is:class TimePeriod {
private $Seconds;public $Hours { get() { return $this->Hours; } final set NULL; }
}
It's close to what's been suggested but is pretty clear that there IS NO
SETTER it could not be called within the class and since its final it
cannot be over-ridden. I've included this in the change tracking document.Thoughts?
-Clint
read-only => final set null;
It begins to be verbose.As I said many times, why don't you want to use the "const" keyword? It
already exists and is pretty well understood by everybody.
Could you maybe explain where exactly "const" would be used? Please
don't forget that we do not use your "foo:bar" syntax, so where would
the "const" go with the currently used syntax?
Anyway, I'd like to give a quick comment on read-only: I mainly don't
like the keyword because it doesn't do what I expect it to do. When I
first glanced over the RFC I thought that read-only was a way to
define read-only properties (i.e. properties that can only be set via
default value or in the constructor) along the lines of "public
read-only $name = 'FooBar';". This is what the "readonly" modifier
means in C# (which is the language the RFC is adopted from mainly). In
C# readonly can not be added to properties with accessors, only to
simple fields. With the current RFC / the original proposal
"read-only" gets a completely different meaning.
I think that the behavior of the modifier in C# is useful, whereas its
behavior in the original accessors proposal is mostly pointless. I
mean, why would you need to strictly enforce that a property is
read-only throughout the inheritance hierarchy? From an interfacing
(LSP) point of view it's not of importance whether an additional set
accessor is added, as long as the get accessor stays. I would guess
that "read-only" will be used about as much as "final" is used today.
And "final" is nearly never used.
That's why I really don't think that we need any kind of special
syntax for this. If you do happen to be the rare case where you need
to enforce the read-only-ness throughout the hierarchy, you can always
use the "final private set()" approach (maybe even throwing an
exception from it so you can't even access it from within the class).
Everything else seems unnecessary to me and would only make things
more complicated than necessary.
Nikita
The usage of the syntax in C# is moderately unimportant. This is a
different language, and property accessors are part of numerous languages -
not just C#. That being said, it's not that big of a deal, as it seems that
most people are in a consensus that we do not want to to be adding any sort
of read only keyword.
The final keyword is used, especially in sizable OOP applications.
Claiming it supposedly isn't used very often anymore - even if it were true
- is not an excuse to exclude the "read-only"-esque functionality in this
RFC.
Amaury brings up an interesting point in that write-only essentially makes
the accessor a method. In my opinion, this needs to be further discussed as
to whether or not we do or do not need write-only. If there are no good
real-world implementations of it other than making a property act like a
method, then we should probably can that idea.
Read-only is still necessary, though in a different syntax. Being able to
set a "final"-esque functionality on the get property accessor function -
as to protect from certain cases, however few there may be - is, in my
opinion, an important, necessary piece of this RFC.
I think const has too many issues, and thus we shouldn't use it. When
setting a variable to a constant in PHP, it changes the way the variable is
called. From $this->property or $variable to *$this::property orvariable
*. Even with const, we still have the same issue that we had with numerous
of the previous proposals:
// Which one?
public $property {
const get();
const get;
const get() {}
final private get;
final private get();
final get NULL;
}// This is what I assume Amaury would prefer, correct? We're not going
with the colon syntax, though, so this example is out of the question...
public:const $property {
set() { ... }
}
Considering we aren't using the colon solution proposed by Amaury, const
still doesn't solve the solution and would just add confusion if we were to
implement it in whatever solution we come up with.
Let's look over our other past and current implementations and proposals:
public $property {
final get;
final get();
final get NULL;
final private get() {} // RFC 1.2 Current Implemented Proposal
}// And of course, from RFC 1.1
public read-only $property {
set() { ... }
}
My top choice is final get;, which would work quite well and
non-ambiguously if we don't implement Nikita's proposed automatic accessor
functions or implement it in a noticeably different syntax.
It's the easiest to write, and it's pretty obvious that it isn't extendable
and doesn't actually do anything, and thus is arguably visually read-only.
My opinion of Clint's proposed final get NULL; is a bit meh - the null
keyword is just spat up on the code and the syntax is a bit too..
unfamiliar for my preference. It would make a lot more sense if it was final
get = NULL; but I don't think we should go that route.
On Sat, Oct 20, 2012 at 9:29 AM, Amaury Bouchard amaury@amaury.net
wrote:read-only => final set null;
It begins to be verbose.As I said many times, why don't you want to use the "const" keyword? It
already exists and is pretty well understood by everybody.
Could you maybe explain where exactly "const" would be used? Please
don't forget that we do not use your "foo:bar" syntax, so where would
the "const" go with the currently used syntax?Anyway, I'd like to give a quick comment on read-only: I mainly don't
like the keyword because it doesn't do what I expect it to do. When I
first glanced over the RFC I thought that read-only was a way to
define read-only properties (i.e. properties that can only be set via
default value or in the constructor) along the lines of "public
read-only $name = 'FooBar';". This is what the "readonly" modifier
means in C# (which is the language the RFC is adopted from mainly). In
C# readonly can not be added to properties with accessors, only to
simple fields. With the current RFC / the original proposal
"read-only" gets a completely different meaning.I think that the behavior of the modifier in C# is useful, whereas its
behavior in the original accessors proposal is mostly pointless. I
mean, why would you need to strictly enforce that a property is
read-only throughout the inheritance hierarchy? From an interfacing
(LSP) point of view it's not of importance whether an additional set
accessor is added, as long as the get accessor stays. I would guess
that "read-only" will be used about as much as "final" is used today.
And "final" is nearly never used.That's why I really don't think that we need any kind of special
syntax for this. If you do happen to be the rare case where you need
to enforce the read-only-ness throughout the hierarchy, you can always
use the "final private set()" approach (maybe even throwing an
exception from it so you can't even access it from within the class).
Everything else seems unnecessary to me and would only make things
more complicated than necessary.Nikita
The final keyword is used, especially in sizable OOP applications. Claiming
it supposedly isn't used very often anymore - even if it were true - is not
an excuse to exclude the "read-only"-esque functionality in this RFC.
Firstly, I didn't make that claim out of thin air, I actually checked
how many final methods are used in ZF and Symfony (which are my usual
reference projects due to their large size) and from that concluded
that "nearly never" is a very accurate description. It could obviously
be that those two projects are somehow special and everyone else uses
large amounts of final methods ;)
Secondly, low anticipated use is actually a very good reason to
exclude functionality. One shouldn't add features from which you know
right from the start that nearly no-one will use them.
Thirdly, I don't want to exclude the possibility of enforcing
read-only-ness through the hierarchy. I just don't want to provide a
dedicated syntax for such an edge case. As already mentioned, there
already are sufficiently simple ways to do this:
// read-only for all classes in the hierarchy, only the current one can read
final private set();
// absolutely read-only
final private set() { throw new ReadonlyPropertyException; }
The latter is even rather clear about the intention ;)
My top choice is final get;, which would work quite well and non-ambiguously
if we don't implement Nikita's proposed automatic accessor functions or
implement it in a noticeably different syntax.
Not sure where you got that, but automatic accessor implementations
are not my idea, they were part of the original proposal. I wanted to
remove them, but later we found that they are necessary for various
aspects of the RFC, in particular asymmetric accessor visibility
(public $foo { get; protected set; }). Unless you want to drop that
too automatic implementations have to stay.
Nikita
Nikita, there appears to be a slight misunderstanding. You're initial email
was worded in a way that I presumed you were attacking the final keyword
entirely, not just final methods. You are correct in that many PHP
frameworks don't have final functions.
My pushing for the read-only functionality is that it, in my opinion,
necessary for cohesiveness with the final keyword.
The read-only implementation we are still working on creating is
essentially a magic version of
final set() { throw new ReadonlyPropertyException; }
In regards to your third point: Clint sent an email a few days wherein he
implied you were the driving factor behind automatic accessors. Sorry for
the confusion.
Asymmetric accessor visibility is a different subject. It's moderately
convenient but I'm worried there's too much magic going on in the
background and it's not apparent what the syntax means. We should probably
open up another discussion thread for this subject, though.
On Sat, Oct 20, 2012 at 11:31 AM, Jazzer Dane tbprogrammer@gmail.com
wrote:The final keyword is used, especially in sizable OOP applications.
Claiming
it supposedly isn't used very often anymore - even if it were true - is
not
an excuse to exclude the "read-only"-esque functionality in this RFC.
Firstly, I didn't make that claim out of thin air, I actually checked
how many final methods are used in ZF and Symfony (which are my usual
reference projects due to their large size) and from that concluded
that "nearly never" is a very accurate description. It could obviously
be that those two projects are somehow special and everyone else uses
large amounts of final methods ;)Secondly, low anticipated use is actually a very good reason to
exclude functionality. One shouldn't add features from which you know
right from the start that nearly no-one will use them.Thirdly, I don't want to exclude the possibility of enforcing
read-only-ness through the hierarchy. I just don't want to provide a
dedicated syntax for such an edge case. As already mentioned, there
already are sufficiently simple ways to do this:// read-only for all classes in the hierarchy, only the current one
can read
final private set();
// absolutely read-only
final private set() { throw new ReadonlyPropertyException; }The latter is even rather clear about the intention ;)
My top choice is final get;, which would work quite well and
non-ambiguously
if we don't implement Nikita's proposed automatic accessor functions or
implement it in a noticeably different syntax.
Not sure where you got that, but automatic accessor implementations
are not my idea, they were part of the original proposal. I wanted to
remove them, but later we found that they are necessary for various
aspects of the RFC, in particular asymmetric accessor visibility
(public $foo { get; protected set; }). Unless you want to drop that
too automatic implementations have to stay.Nikita
2012/10/20 Nikita Popov nikita.ppv@gmail.com
Could you maybe explain where exactly "const" would be used?
Well "const" and "read-only" have the exact same meaning. You can replace
one by the other. So why create a new keyword?
Please
don't forget that we do not use your "foo:bar" syntax, so where would
the "const" go with the currently used syntax?
Don't be rude. It's not a "foo:bar" syntax sent no matter how on this
mailing-list. It was an argumented RFC proposal, with an associated patch
(but yeah, who cares?).
If you want to give it a silly nickname, I'd prefer "public:private". :-)
The RFC was:
public read-only $a {
get { return $this->_a; }
}
It could be:
public const $a {
get { return $this->_a; }
}
Is it so different that it needs a new keyword?
I would like to point out that in my mind const
and read-only
are
not necessarily the same thing. Read-only means that from outside the
class it cannot be modified; the internal class can change it whenever
it wants. Const means that once the value is set it will NEVER change.
Big difference.
Also, I feel like there is no need for the read-only keyword.
Defining a getter and not a setter should suffice in my opinion. The
absence of the setter declares intent well, in my opinion. If for some
reason you need to enforce that nobody inherits it and sets the
property, then declaring a setter and issuing an error or exception
would suffice. Let's not clutter up the language for such a simple
idea.
If for some reason you need to enforce that nobody inherits it
and sets the property, then declaring a setter and issuing an
error or exception would suffice.
I meant to say declaring a private or final setter
. Noticed that
after I sent it.
I think that seems to be the consensus at this point, anyone disagree?
-----Original Message-----
From: Levi Morrison [mailto:morrison.levi@gmail.com]
Sent: Sunday, October 21, 2012 10:26 AM
To: Amaury Bouchard
Cc: Nikita Popov; Clint Priest; internals@lists.php.net
Subject: Re: [PHP-DEV] [RFC] Accessors : read-only / write-only keywordsIf for some reason you need to enforce that nobody inherits it and
sets the property, then declaring a setter and issuing an error or
exception would suffice.I meant to say declaring a
private or final setter
. Noticed that after I sent it.
I don't disagree (sure, I campaigned to remove the "read-only" keyword).
But "not writable" is still different from "private writing". Should we
loose any of these meanings?
2012/10/21 Clint Priest cpriest@zerocue.com
I think that seems to be the consensus at this point, anyone disagree?
-----Original Message-----
From: Levi Morrison [mailto:morrison.levi@gmail.com]
Sent: Sunday, October 21, 2012 10:26 AM
To: Amaury Bouchard
Cc: Nikita Popov; Clint Priest; internals@lists.php.net
Subject: Re: [PHP-DEV] [RFC] Accessors : read-only / write-only keywordsIf for some reason you need to enforce that nobody inherits it and
sets the property, then declaring a setter and issuing an error or
exception would suffice.I meant to say declaring a
private or final setter
. Noticed that
after I sent it.
2012/10/21 Levi Morrison morrison.levi@gmail.com
I would like to point out that in my mind
const
andread-only
are
not necessarily the same thing. Read-only means that from outside the
class it cannot be modified; the internal class can change it whenever
it wants. Const means that once the value is set it will NEVER change.
Big difference.
"read-only" means that it is only readable. Like const.
If the internal class can change it, you are defining writing visibility
(as private or protected).
Yes, it is different. Visibility has far more meaning than just saying it's
a constant value. In fact, "read-only" is a sub-case of usual visibility
management.
read-only => final set null;
It begins to be verbose.
There is nothing wrong with being verbose. PHP has always been verbose,
which IMO is a strong point of the language as it makes everything a lot
easier to search for.
cheers,
Derick
--
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine
2012/10/20 Derick Rethans derick@php.net
There is nothing wrong with being verbose. PHP has always been verbose,
which IMO is a strong point of the language as it makes everything a lot
easier to search for.
There is a confusion between being verbose and being explicit.
PHP syntax is explicit. Verbosity is not a goal.
Hi!
get() { return $this->Hours; } final set NULL;
It looks like some unobvious piece of magic - what exactly "set NULL"
means? There's no obvious parsing of this thing for somebody that
doesn't already know what the magic means. I'd rather have people
implement a method throwing exception manually than have this. It's
unclear what is relationship between "set" (is it a variable? a
constant? a method?) and "NULL" (what NULL
here means? is it assignment
of NULL
to set? is it declaration of NULL
with type "set"?) and it does
not parse naturally with almost any background.
Thinking about it for a while, the whole idea of "this class can never
have this method implemented" looks a bit strange to me - I don't think
I've ever encountered such concept in OOP. You can say "I implement it
this way and you can't override it" but NULL
does not suggest any
natural implementation.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I'll agree with you in regards to your analysis of Clint's proposed syntax.
In terms of your questioning the idea around "read-only", this is how I
think about it:
Class A created property accessor $z that you can not set. Class B can
extend me just fine, but they can not alter that basic rule that I laid out
for my and all my children's property accessor $z: You can not set it.
This makes sense to me, and I feel like it is control that the developer
should have.
If we were to translate final set NULL; (or whatever implementation we
choose to use) to a more manual implementation, it may look something like
this:
public $property {
final get() { ... }
final set($value) { throw new Exception("You can't set $property. It is
read only."); }
}
On Sat, Oct 20, 2012 at 2:40 AM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
get() { return $this->Hours; } final set NULL;
It looks like some unobvious piece of magic - what exactly "set NULL"
means? There's no obvious parsing of this thing for somebody that
doesn't already know what the magic means. I'd rather have people
implement a method throwing exception manually than have this. It's
unclear what is relationship between "set" (is it a variable? a
constant? a method?) and "NULL" (whatNULL
here means? is it assignment
ofNULL
to set? is it declaration ofNULL
with type "set"?) and it does
not parse naturally with almost any background.Thinking about it for a while, the whole idea of "this class can never
have this method implemented" looks a bit strange to me - I don't think
I've ever encountered such concept in OOP. You can say "I implement it
this way and you can't override it" butNULL
does not suggest any
natural implementation.--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
Class A created property accessor $z that you can not set. Class B can
extend me just fine, but they can not alter that basic rule that I laid
out for my and all my children's property accessor $z: You can not set it.
I'm fine with the idea of methods that are not overrideable, even though
I think the real use case for it is not that big. I'm less fine with the
idea of methods that are not definable. Whole "final NULL" business
seems weird to me.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I had thought of a deviation on some of the ideas presented to get rid of read-only/write-only while still keeping the ability to maintain their effect, if we so decide that the feature is wanted. Here it is:
class TimePeriod {
private $Seconds;public $Hours { get() { return $this->Hours; } final set NULL; }
}
It's close to what's been suggested but is pretty clear that there IS NO SETTER it could not be called within the class and since its final it cannot be over-ridden. I've included this in the change tracking document.
Thoughts?
Sorry but I don't like it, it makes me think that there is no setter
but I could set the property manually (yes, that's not an actual one
but putting myself in the shoes of a lambda user).
I actually prefer the read-only syntax, while we have to make it clear
and not confusin (see Niki's reply in this post).
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Nikita brought up a good point:
There aren't all that many scripts that use final methods, which could very
well be the same fate for final property accessor methods.
Due to the very possible unpopularity of whatever magic syntax/keyword we
could potentially come up with, we *could *alternatively trash any magic
read/write-only keywords/syntax and just allow people to manually throw a
read-only exception.
Opinions?
I had thought of a deviation on some of the ideas presented to get rid
of read-only/write-only while still keeping the ability to maintain their
effect, if we so decide that the feature is wanted. Here it is:class TimePeriod {
private $Seconds;public $Hours { get() { return $this->Hours; } final set NULL; }
}
It's close to what's been suggested but is pretty clear that there IS NO
SETTER it could not be called within the class and since its final it
cannot be over-ridden. I've included this in the change tracking document.Thoughts?
Sorry but I don't like it, it makes me think that there is no setter
but I could set the property manually (yes, that's not an actual one
but putting myself in the shoes of a lambda user).I actually prefer the read-only syntax, while we have to make it clear
and not confusin (see Niki's reply in this post).Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
On 20-10-2012 19:20, Clint Priest wrote:> Hey Rasmus, please try and
keep these replies in the appropriate thread...
I am in favor of eliminating the read-only/write-only keywords and
implementing no "special code" to make what was read-only/write-only
language enforced. I think the alternatives with final are just fine
and good enough and will let userland programming enforce it if they so
desire.Example of user-land enforced 'read-only' code:
class A {
public $b {
get() { ... }
private final set($x) { throw new Exception("cannot set $b"); }
}
}This solution introduces no magic on the engine side and lets those
who need a read-only / write-only type scenario to "work."Does this sound like an effective solution for everyone?
Ok, time to put it in the correct thread again, with actual working
threading.
For the last few days I've been wondering why the hell anyone would
really need a write-only keyword; and the only answer to this that I
could think of was that "it would be nice" since you could catch such
problems automatically, instead of actually having to write additional
custom code which prevents access to the set-accessor. Apart from that,
there is also the thing that using this additional keyword you can (if
implemented at all) show that such a method does NOT exist in interfaces
/ reflection.
Anyway, the 'solution' of not adding a lot of confusing keywords to say
something that can be said simply using code inside the function...
seems very good to me. I must admit I'm surprised noone has brought it
up till yesterday.
- Tul (casual internals reader)