# [RFC] Accessors : read-only / write-only keywords

- Thread: https://externals.io/message/63548
- Original archive: https://news-web.php.net/php.internals/63548
- Started by Clint Priest on 2012-10-19T23:07:21+00:00
- Messages: 20
- 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

---

## #63548 — Clint Priest — 2012-10-19T23:07:21+00:00

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

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

---

## #63549 — Amaury Bouchard — 2012-10-20T07:29:49+00:00

URL: https://externals.io/message/63548#63549 · In reply to: #63548

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

---

## #63551 — Nikita Popov — 2012-10-20T09:05:00+00:00

URL: https://externals.io/message/63548#63551 · In reply to: #63549

>   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

---

## #63552 — Derick Rethans — 2012-10-20T09:30:05+00:00

URL: https://externals.io/message/63548#63552 · In reply to: #63549

>   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

---

## #63554 — Jazzer Dane — 2012-10-20T09:31:30+00:00

URL: https://externals.io/message/63548#63554 · In reply to: #63551

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 *or*variable
*. 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:
> > […]
> 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

---

## #63555 — Stas Malyshev — 2012-10-20T09:40:50+00:00

URL: https://externals.io/message/63548#63555 · In reply to: #63548

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

---

## #63556 — Jazzer Dane — 2012-10-20T09:49:13+00:00

URL: https://externals.io/message/63548#63556 · In reply to: #63555

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.com>wrote:

> Hi!
>
> > […]
>
> 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

---

## #63557 — Nikita Popov — 2012-10-20T09:52:24+00:00

URL: https://externals.io/message/63548#63557 · In reply to: #63554

> 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

---

## #63559 — Jazzer Dane — 2012-10-20T10:15:12+00:00

URL: https://externals.io/message/63548#63559 · In reply to: #63557

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:
> > […]
> Claiming
> > […]
> not
> > […]
> 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 ;)
>
> > […]
> non-ambiguously
> > […]
> 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

---

## #63558 — Pierre Joye — 2012-10-20T10:15:13+00:00

URL: https://externals.io/message/63548#63558 · In reply to: #63548

> 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

---

## #63561 — Jazzer Dane — 2012-10-20T10:21:24+00:00

URL: https://externals.io/message/63548#63561 · In reply to: #63558

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?



> 
> > […]
> 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:
> > […]
> 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.
> > […]
>
> 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

---

## #63562 — Amaury Bouchard — 2012-10-20T10:37:12+00:00

URL: https://externals.io/message/63548#63562 · In reply to: #63551

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?

---

## #63563 — Stas Malyshev — 2012-10-20T10:40:36+00:00

URL: https://externals.io/message/63548#63563 · In reply to: #63556

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

---

## #63564 — Amaury Bouchard — 2012-10-20T11:07:27+00:00

URL: https://externals.io/message/63548#63564 · In reply to: #63552

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.

---

## #63572 — Maciek Sokolewicz — 2012-10-20T19:58:46+00:00

URL: https://externals.io/message/63548#63572 · In reply to: #63548

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)

---

## #63587 — Levi Morrison — 2012-10-21T15:23:53+00:00

URL: https://externals.io/message/63548#63587 · In reply to: #63562

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.

---

## #63588 — Levi Morrison — 2012-10-21T15:25:51+00:00

URL: https://externals.io/message/63548#63588 · In reply to: #63587

> 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.

---

## #63589 — Clint Priest — 2012-10-21T15:34:03+00:00

URL: https://externals.io/message/63548#63589 · In reply to: #63588

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 keywords
> 
> > […]
> 
> I meant to say declaring a `private or final setter`.  Noticed that after I sent it.

---

## #63595 — Amaury Bouchard — 2012-10-21T18:53:58+00:00

URL: https://externals.io/message/63548#63595 · In reply to: #63587

2012/10/21 Levi Morrison <morrison.levi@gmail.com>

> 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.
>

"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.

---

## #63596 — Amaury Bouchard — 2012-10-21T19:02:12+00:00

URL: https://externals.io/message/63548#63596 · In reply to: #63589

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?
>
> > […]
> after I sent it.
