# Final properties

- Thread: https://externals.io/message/92084
- Original archive: https://news-web.php.net/php.internals/92084
- Started by michal@brzuchalski.com on 2016-04-04T17:53:46+00:00
- Messages: 29
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/92084.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #92084 — michal@brzuchalski.com — 2016-04-04T17:53:46+00:00

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

Hey Internals,

I'm new here. I've been wondering / working on adding final properties into
PHP lang.

This work started once I had the time to read the "Core Java for
Impateient" by Cay S. Horstmann
and found it very usefull to have final properties like Java.

Those properties differ than `const` because they can be set at runtime -
but only once in their lifetime.
Such properties could be very usefull in Singletons, ValueObjects etc. impl
like:

class Money {
    public final $amount;
    public final $currency;
    public function __constructor($amount, $currency) {
        $this->amount = $amount;
        $this->currency = $currency;
    }
}

In above example there is even no need for getter because those properties
are immutable through
the final keyword, it means those properties cannot change their references
just like in Java
https://en.wikipedia.org/wiki/Final_(Java)

I've already started some impl on own fork
https://github.com/php/php-src/compare/master...brzuchal:final-properties
I've got some basics in C programming, don't know yet if I can impl it
complex.

I was wondering if it is usefull in yours opinion or is it only my
impression.

I can provide an RFC if it sounds usefull and if I get Wiki karma

Thanks
--
Michał Brzuchalski (aka brzuchal)

---

## #92091 — Marco Pivetta — 2016-04-05T09:13:26+00:00

URL: https://externals.io/message/92084#92091 · In reply to: #92084

Hi Michał,

First of all: +1 to this: very useful for value objects!

A few questions:

 * can you re-declare a final property in a sub-class, making it therefore
non-final? (I have reasons to do that, related with altering states via
mappers)
 * do we want to use `final`, or `immutable` for these properties? `final`
seems to just be a confusing term here.
 * is this feature portable to variables in general? I realize that adding
metadata to ZVals has huge performance implications, but it would be
interesting to do that for performance improvements further down the line

Cheers,


Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/



> Hey Internals,
>
> I'm new here. I've been wondering / working on adding final properties into
> PHP lang.
>
> This work started once I had the time to read the "Core Java for
> Impateient" by Cay S. Horstmann
> and found it very usefull to have final properties like Java.
>
> Those properties differ than `const` because they can be set at runtime -
> but only once in their lifetime.
> Such properties could be very usefull in Singletons, ValueObjects etc. impl
> like:
>
> class Money {
>     public final $amount;
>     public final $currency;
>     public function __constructor($amount, $currency) {
>         $this->amount = $amount;
>         $this->currency = $currency;
>     }
> }
>
> In above example there is even no need for getter because those properties
> are immutable through
> the final keyword, it means those properties cannot change their references
> just like in Java
> https://en.wikipedia.org/wiki/Final_(Java)
>
> I've already started some impl on own fork
> https://github.com/php/php-src/compare/master...brzuchal:final-properties
> I've got some basics in C programming, don't know yet if I can impl it
> complex.
>
> I was wondering if it is usefull in yours opinion or is it only my
> impression.
>
> I can provide an RFC if it sounds usefull and if I get Wiki karma
>
> Thanks
> --
> Michał Brzuchalski (aka brzuchal)

---

## #92093 — michal@brzuchalski.com — 2016-04-05T10:06:18+00:00

URL: https://externals.io/message/92084#92093 · In reply to: #92091

Hi Marco,

Ad. 1 it is posiible to redeclare in a sub-class final property as
non-final, here is some gist presenting my current impl working like:
https://gist.github.com/brzuchal/12ebda1efed59440a78ba43bff116728

Ad. 2. `final` means class variable (like static) or class instance
property can not change their reference, it is impossible to replace zval
in such property, in my opinion `immutable` is object behavior when using
some methods you receive newly created (cloned) object which is changed
exactly like `DateTimeImmutable`
http://php.net/manual/en/datetimeimmutable.add.php

Ad. 3 it would be awesome if there could be final variables in general, it
would be quite stable if no one could change your variable, AFAIK zvals
have IMMUTABLE flag which could be used, don't know it for sure I'm rather
PHP dev than C there would be need some internals guru to ask if it's
posiible.

P.S. We've meet on PHPCon'15 in Poland, thanks for +1.

Cheers,
--
Michał Brzuchalski (aka brzuchal)

2016-04-05 11:13 GMT+02:00 Marco Pivetta <ocramius@gmail.com>:

> Hi Michał,
>
> First of all: +1 to this: very useful for value objects!
>
> A few questions:
>
>  * can you re-declare a final property in a sub-class, making it therefore
> non-final? (I have reasons to do that, related with altering states via
> mappers)
>  * do we want to use `final`, or `immutable` for these properties? `final`
> seems to just be a confusing term here.
>  * is this feature portable to variables in general? I realize that adding
> metadata to ZVals has huge performance implications, but it would be
> interesting to do that for performance improvements further down the line
>
> Cheers,
>
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>
> On 4 April 2016 at 19:53, Michał Brzuchalski <michal@brzuchalski.com>
> wrote:
>
> > […]

---

## #92094 — Marco Pivetta — 2016-04-05T10:13:48+00:00

URL: https://externals.io/message/92084#92094 · In reply to: #92093

Hi,



> Hi Marco,
>
> Ad. 1 it is posiible to redeclare in a sub-class final property as
> non-final, here is some gist presenting my current impl working like:
> https://gist.github.com/brzuchal/12ebda1efed59440a78ba43bff116728
>

Does this work for public properties as well?


> Ad. 2. `final` means class variable (like static) or class instance
> property can not change their reference, it is impossible to replace zval
> in such property, in my opinion `immutable` is object behavior when using
> some methods you receive newly created (cloned) object which is changed
> exactly like `DateTimeImmutable`
> http://php.net/manual/en/datetimeimmutable.add.php
>

I am aware of what `final` means in other languages, it just seems that
everyone then needs to translate back and forth from `final` to
`immutable`. In addition to that, `final` has different meaning in
inheritance (re-used keyword), so this adds to the confusion for people
unfamiliar with the feature.


> Ad. 3 it would be awesome if there could be final variables in general, it
> would be quite stable if no one could change your variable, AFAIK zvals
> have IMMUTABLE flag which could be used, don't know it for sure I'm rather
> PHP dev than C there would be need some internals guru to ask if it's
> posiible.
>
> P.S. We've meet on PHPCon'15 in Poland, thanks for +1.
>

YW!


>
> Cheers,
> --
> Michał Brzuchalski (aka brzuchal)
>
> 2016-04-05 11:13 GMT+02:00 Marco Pivetta <ocramius@gmail.com>:
>
> > […]
>
As an additional question: how will this (eventually) play with typed
properties? I am aware that you cannot declare a class named `final`, but
that may change in future, so better factor it into any possible outcomes
of the RFC.

Cheers,

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #92095 — michal@brzuchalski.com — 2016-04-05T10:57:47+00:00

URL: https://externals.io/message/92084#92095 · In reply to: #92094

Hi,

2016-04-05 12:13 GMT+02:00 Marco Pivetta <ocramius@gmail.com>:

> Hi,
>
> On 5 April 2016 at 12:06, Michał Brzuchalski <michal@brzuchalski.com>
> wrote:
>
> > […]
>
>
It works with public, private and protected properties.


> Does this work for public properties as well?
>
>
> > […]
>
> I am aware of what `final` means in other languages, it just seems that
> everyone then needs to translate back and forth from `final` to
> `immutable`. In addition to that, `final` has different meaning in
> inheritance (re-used keyword), so this adds to the confusion for people
> unfamiliar with the feature.
>
> Wiki about Final in Java
https://www.wikiwand.com/en/Final_(Java)#/Final_variables says:

# Final variables
A final variable can only be initialized once, either via an initializer or
an assignment statement. It does not need to be initialized at the point of
declaration: this is called a "blank final" variable. A blank final
instance variable of a class must be definitely assigned in every
constructor of the class in which it is declared; similarly, a blank final
static variable must be definitely assigned in a static initializer of the
class in which it is declared; otherwise, a compile-time error occurs in
both cases.[6] (Note: If the variable is a reference, this means that the
variable cannot be re-bound to reference another object. But the object
that it references is still mutable, if it was originally mutable.)

I took the name from Java and only implemented behavior like that, thats wy
I used `final`.


> > […]
>
> YW!
>
>
> > […]
> As an additional question: how will this (eventually) play with typed
> properties? I am aware that you cannot declare a class named `final`, but
> that may change in future, so better factor it into any possible outcomes
> of the RFC.
>
> I don't know if it works with typed properties.
I can provide an RFC but need Wiki Karma (or smth like that) for my account
(login: brzuchal) and don't know how to receive it.


> Cheers,
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>

Cheers,
--
Michał Brzuchalski (aka brzuchal)

---

## #92123 — Chris Riley — 2016-04-05T16:28:20+00:00

URL: https://externals.io/message/92084#92123 · In reply to: #92095

> Hi,
>
> 2016-04-05 12:13 GMT+02:00 Marco Pivetta <ocramius@gmail.com>:
>
> > […]
> It works with public, private and protected properties.
>
>
> > […]
> zval
> > […]
> using
> > […]
> https://www.wikiwand.com/en/Final_(Java)#/Final_variables says:
>
> # Final variables
> A final variable can only be initialized once, either via an initializer or
> an assignment statement. It does not need to be initialized at the point of
> declaration: this is called a "blank final" variable. A blank final
> instance variable of a class must be definitely assigned in every
> constructor of the class in which it is declared; similarly, a blank final
> static variable must be definitely assigned in a static initializer of the
> class in which it is declared; otherwise, a compile-time error occurs in
> both cases.[6] (Note: If the variable is a reference, this means that the
> variable cannot be re-bound to reference another object. But the object
> that it references is still mutable, if it was originally mutable.)
>
> I took the name from Java and only implemented behavior like that, thats wy
> I used `final`.
>
>
> > […]
> zvals
> > […]
> rather
> > […]
> would be
> > […]
> line
> > […]
> runtime
> > […]
> https://github.com/php/php-src/compare/master...brzuchal:final-properties
> > […]
> I can provide an RFC but need Wiki Karma (or smth like that) for my account
> (login: brzuchal) and don't know how to receive it.
>
>
> > […]
>
> Cheers,
> --
> Michał Brzuchalski (aka brzuchal)
>

I started a discussion on this a while back, but it fizzled due to not
having an elegant solution for the 'give me a new one of these with these
values changed' problem. I would HIGHLY suggest not using the final
keyword. If final is used as a keyword I would expect it to mean that this
property definition cannot be changed in a child class. See:
https://marc.info/?l=php-internals&m=144766539202647&w=2 Would be happy to
pick this up again and help get the RFC created.

---

## #92127 — Marco Pivetta — 2016-04-05T16:39:12+00:00

URL: https://externals.io/message/92084#92127 · In reply to: #92123

>
> I started a discussion on this a while back, but it fizzled due to not
> having an elegant solution for the 'give me a new one of these with these
> values changed' problem. I would HIGHLY suggest not using the final
> keyword. If final is used as a keyword I would expect it to mean that this
> property definition cannot be changed in a child class. See:
> https://marc.info/?l=php-internals&m=144766539202647&w=2 Would be happy
> to pick this up again and help get the RFC created.
>

Same concern here: just because Java decided that `final` means
`assign-once`, it doesn't mean php should adopt it too.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #92118 — michal@brzuchalski.com — 2016-04-05T19:09:20+00:00

URL: https://externals.io/message/92084#92118

Hi Robert, Marco and Chris,

now I see your point. Lastly I've found in DZone newsletter about Java
putting `var` and `val` keywords, interesting is the second which is going
to be used in case of immutable "variables" like a "values" (that's where
`val` came from) see here http://openjdk.java.net/jeps/286 at "Syntax
Choices" section. Checked C# for such feature and found out that there is
something like `sealed` keyword which prevents from changing reference and
also `readonly` keyword which states for property read only everywhere
except class constructor (interesting isn't it?).

I also read about "Immutable modifier" discussion and IMHO it looks like
it's about time to get such feature.

I also agree that `final` keyword may be not so good choice for
immutability, I've checked Scala, Kotlin and Swift about final properties
and it looks like there it is used to unable to override property
accedentally, and putting additional `override` (see
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html)
section "Overriding" says:
"To override a characteristic that would otherwise be inherited, you prefix
your overriding definition with the `override` keyword. Doing so clarifies
that you intend to provide an override and have not provided a matching
definition by mistake. Overriding by accident can cause unexpected
behavior, and any overrides without the override keyword are diagnosed as
an error when your code is compiled."

Considerring all of that thoughts I think that `final` keyword in
properties declaration whould be awesome with Typed Properties
https://wiki.php.net/rfc/typed-properties keeping to not override the Type
Hint declaration.

I'll try my best to continue implementation of somehow immutable variables
as they would be great at ValueObjects impl.
The choice for proprietary keyword could be a subject of discuccion.

Cheers,
--
Michał


2016-04-05 20:08 GMT+02:00 Robert Stoll <php@tutteli.ch>:

> Hi Marco,
> > […]
> everyone then needs to translate back and forth
> > […]
> meaning in inheritance (re-used keyword), so this adds
> > […]
>
> I think immutable is also not ideal because to me, it sounds like the
> whole object is immutable even though only the property is. I do not know a
> better solution than final though
>
> Cheers,
> Robert

---

## #92134 — Fleshgrinder — 2016-04-07T17:35:05+00:00

URL: https://externals.io/message/92084#92134 · In reply to: #92095

/Sending this again because the mail server was down./

+1 from my side too for this proposal. Retrofitting immutability with
additional keywords is not the nicest thing but PHP has no other way
(same was true for Java when they added it).

Using the *final* keyword while subclasses are able to override it is
ambiguous in PHP because it already has the notion that something is not
extensible (class) or overridable (method). Hence, I would either use a
different keyword or implement two keywords (and two RFCs):

1. *immutable* for the functionality you are currently working on.
2. *sealed* for the above plus type not changeable.
3. *final* for the above plus not being overridable.

Opening restrictions should be possible as with widening visibility in
inheritance but making something more tight should not because it would
violate the (implicit) interface of the parent class. In other words:

    OK
    ==
    immutable -> mutable
    sealed -> immutable
    sealed -> mutable

    Fatal Error
    ===========
    immutable -> sealed
    immutable -> final
    sealed -> final
    final -> immutable
    final -> sealed
    final -> mutable
    mutable -> immutable
    mutable -> sealed
    mutable -> final

Of course it would be nice to have the possibility to disable these
restrictions while creating fakes, mocks, ... in unit tests. Sadly that
is a feature that we don't have at all in PHP; e.g.:

    final class ClassUnderTest {}

    mock class TestDouble extends ClassUnderTest {}

I do not think that there should be anything that prevents this new
feature to work nicely together with typed properties. Of course I could
be wrong here but then again it might only require a few adoptions of
that feature to work nicely. One thing is for sure, *immutable*,
*sealed* and *final* would also disallow references (e.g. sorting of an
array); which is a good thing.

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92179 — Sebastian Bergmann — 2016-04-09T07:39:03+00:00

URL: https://externals.io/message/92084#92179 · In reply to: #92091

Am 05.04.2016 um 11:13 schrieb Marco Pivetta:
> First of all: +1 to this: very useful for value objects!

 My thought exactly.

>  do we want to use `final`, or `immutable` for these properties?

 I have the same sentiment you have, that "final" would be confusing
 and "immutable" would be better. But it's also confusing to have
 the same concept another language has under a different name. Hm.

 I think I tend towards "immutable".

---

## #92181 — andre.romcke@ez.no — 2016-04-09T09:59:14+00:00

URL: https://externals.io/message/92084#92181 · In reply to: #92179

> 
> 
> Am 05.04.2016 um 11:13 schrieb Marco Pivetta:
> > […]
> 
> My thought exactly.


Big +1 on this feature for the exact same reasons.

> 
> > […]
> 
> I have the same sentiment you have, that "final" would be confusing
> and "immutable" would be better. But it's also confusing to have
> the same concept another language has under a different name. Hm.
> 
> I think I tend towards "immutable".

I tend to as well. However as noted on misc C# pages* about immutable, this can be slightly confusing also; If the variable is ArrayAccess you will still be able to call offsetSet on it. “readonly"** would be another option, even if some might assume class can always write to it.

Since there is no perfect name, maybe let the name be open for vote as part of RFC? To avoid to much focus on the naming during discussions/specification?

* http://stackoverflow.com/a/6849164
** https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx

---

## #92182 — Niklas Keller — 2016-04-09T10:55:41+00:00

URL: https://externals.io/message/92084#92182 · In reply to: #92181

Another possible choice would be "readonly".

---

## #92183 — Sebastian Bergmann — 2016-04-09T13:52:40+00:00

URL: https://externals.io/message/92084#92183 · In reply to: #92182

Am 09.04.2016 um 12:55 schrieb Niklas Keller:
> Another possible choice would be "readonly".

 Rather "writeonce", no?

---

## #92184 — Niklas Keller — 2016-04-09T14:54:33+00:00

URL: https://externals.io/message/92084#92184 · In reply to: #92183

Readonly is already used in the documentation for some things in the DOM
book. Writeonce sounds strange.

Sebastian Bergmann <sebastian@php.net> schrieb am Sa., 9. Apr. 2016 15:52:

> Am 09.04.2016 um 12:55 schrieb Niklas Keller:
> > […]
>
>  Rather "writeonce", no?

---

## #92187 — Larry Garfield — 2016-04-11T04:59:39+00:00

URL: https://externals.io/message/92084#92187 · In reply to: #92094

> > […]
> I am aware of what `final` means in other languages, it just seems that
> everyone then needs to translate back and forth from `final` to
> `immutable`. In addition to that, `final` has different meaning in
> inheritance (re-used keyword), so this adds to the confusion for people
> unfamiliar with the feature.

There's an important point here that should not be missed.  If these 
values are "write once then locked', which I can definitely see as 
useful, we need to have another shot at modifying them from __clone().  
If not, they are effectively useless for implementing objects in the 
style of DateTimeImmutable or the PSR-7 Request/Response objects.  
Locking after __construct or __clone (as appropriate) is done is fine, 
but if we can't clone-and-modify then I would pretty much never find 
value in this feature (no pun intended).

I agree that final seems like a potentially confusing keyword, as every 
other use of final (AFAIK) means "subclass cannot change this", but 
that's not at all the meaning here.

Another question, which unfortunately runs straight into the previous 
Properties RFC: If a public property is write-once, with the intent 
being that it's set from the constructor and then cannot be overridden 
but is publicly exposed... shouldn't an interface be able to declare it 
as well?  It makes public properties safe to use in some cases, but you 
can't rely on that safely without an interface.

(Which leads to "can interfaces define properties", which leads right 
back to "well what can you do with them", which leads back to the 
Properties RFC. Which I still want to see happen at some point if at all 
possible, as it would also subsume this question quite nicely.)

--Larry Garfield

---

## #92189 — andre.romcke@ez.no — 2016-04-11T10:51:20+00:00

URL: https://externals.io/message/92084#92189 · In reply to: #92187

> 
> ...
> (Which leads to "can interfaces define properties", which leads right back to "well what can you do with them", which leads back to the Properties RFC. Which I still want to see happen at some point if at all possible, as it would also subsume this question quite nicely.)
> 

And by Properties RFC you mean Property Accessors Syntax RFC right?
https://wiki.php.net/rfc/propertygetsetsyntax-v1.2

---

## #92190 — Quim Calpe — 2016-04-11T11:17:15+00:00

URL: https://externals.io/message/92084#92190 · In reply to: #92184

There is a concept in storage devices that fits: Write Once Read Many
(WORM) https://en.wikipedia.org/wiki/Write_once_read_many

final class Value {
    public worm $name;
    public function __construct(string $name) {
        $this->name = $name;
    }
}

I'm not aware of any programming language using this term so it's a bit
awkward in that sense...




> Readonly is already used in the documentation for some things in the DOM
> book. Writeonce sounds strange.
>
> Sebastian Bergmann <sebastian@php.net> schrieb am Sa., 9. Apr. 2016 15:52:
>
> > […]

---

## #92191 — Lin Yo-An — 2016-04-11T11:30:42+00:00

URL: https://externals.io/message/92084#92191 · In reply to: #92190

I would prefer putting the "final" keyword before the "public".

    final public $items;

Since we should emphasis "final" rather than "public"

---

## #92200 — Fleshgrinder — 2016-04-11T16:50:46+00:00

URL: https://externals.io/message/92084#92200 · In reply to: #92184

/Sending this again because the PHP mail server was down./

I thought some more about it and I think that the best choices would be
*val* (for /value/) and *var* (for /variable/) as in Scala.

Why?

The *var* keyword is not going to be deprecated and its meaning is
currently kind of ambiguous. I tried to assign it a new meaning in the
thread about /Access and Visibility Modifiers/ thread
(http://marc.info/?l=php-internals&m=146005798902985&w=2) but as Rowan
Collins pointed out, it would be kind of weird to continue using *var*
for anything related to access/visibility because it simply means
something else; it means /variable/.

The introduction of a counterpart to it would allow it to finally have a
meaningful functionality and it would not introduce any kind of BC for
old code.

    class Foo {

        val $x;

        var $y;

        val $z;

    }

    class Bar extends Foo {

        var $x;

        $y;

        $z;

    }

The parent defines its property as being a *val* (immutable) and the
extending class lifts this constraint by redeclaring it as a *var*
(mutable). Doing so ensures that the developer must know what she is
doing and hence makes the language overall more secure.

There is no BC for the /y/ property because the parent is already
mutable and implicit public (or hopefully /assembly visible/ in the
future, see other references thread), hence, the /y/ in the child class
simply stays mutable.

The /z/ will stay a *val* (immutable) because its parent declaration is
defined as such.

    class Point {

        final public float val $x = 0.0;

        final public float val $y = 0.0;

    }

    final class Point3d extends Point {

        final public float val $z = 0.0;

    }

    final class MutablePoint extends Point {

        final public float var $x; // FATAL ERROR

        final public float var $y; // FATAL ERROR

    }

The *final* keyword could be added via another RFC and it would have the
same meaning as the *final* keyword for classes and methods: freeze the
definition. This is why the *MutablePoint* results in fatal errors: it
tries to redeclare /x/ and /y/ from *val* to *var* although they are
*final*.

Note that this could be easily extended to local variables at a later
stage as well and it would be extremely useful.

I think that Scala's *val*/*var* approach could really help us to make
*var* usable again in a meaningful manner and it corresponds nicely to
the concept of /value objects/ and related concepts with its naming scheme.

What do you think?

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92202 — Fleshgrinder — 2016-04-11T17:12:39+00:00

URL: https://externals.io/message/92084#92202 · In reply to: #92187

> There's an important point here that should not be missed.  If these
> values are "write once then locked', which I can definitely see as
> useful, we need to have another shot at modifying them from __clone(). 
> If not, they are effectively useless for implementing objects in the
> style of DateTimeImmutable or the PSR-7 Request/Response objects. 
> Locking after __construct or __clone (as appropriate) is done is fine,
> but if we can't clone-and-modify then I would pretty much never find
> value in this feature (no pun intended).
> 

*__clone* support is indeed extremely important, very good point.

> I agree that final seems like a potentially confusing keyword, as every
> other use of final (AFAIK) means "subclass cannot change this", but
> that's not at all the meaning here.
> 

See other messages of mine in this thread.

> Another question, which unfortunately runs straight into the previous
> Properties RFC: If a public property is write-once, with the intent
> being that it's set from the constructor and then cannot be overridden
> but is publicly exposed... shouldn't an interface be able to declare it
> as well?  It makes public properties safe to use in some cases, but you
> can't rely on that safely without an interface.
> 
> (Which leads to "can interfaces define properties", which leads right
> back to "well what can you do with them", which leads back to the
> Properties RFC. Which I still want to see happen at some point if at all
> possible, as it would also subsume this question quite nicely.)
> 

I do not see the relation to the RFC (not judging the actual RFC because
I liked the idea but never got into the topic to be able to judge) but I
understand the concern.

In my opinion interfaces in PHP are at the state of Java 7 interfaces
(or even a direct copy) and their functionality must be extended at some
point. Same happened in Java 8.

That being said, I agree that properties should be allowed in
interfaces, however, they must be automatically made *final* and
immutable (where I proposed the *val* keyword).

    interface Example {

        DateTimeImmutable $created;

        function example();

    }

Transforms to:

    interface Example {

        final public DateTimeImmutable val $created;

        public function example();

    }

Otherwise no consumer could rely on the interface to not change. Also
note that it does not require the RFC you mentioned because no setter,
unset, nor isset is necessary or possible if we handle it like this.

Support for mutable public properties is a different story but allowing
them would destroy the encapsulation and I am against it without anyone
bringing some good arguments that convince me.

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92203 — Fleshgrinder — 2016-04-11T17:22:57+00:00

URL: https://externals.io/message/92084#92203 · In reply to: #92202

> Support for mutable public properties is a different story but allowing
> them would destroy the encapsulation and I am against it without anyone
> bringing some good arguments that convince me.
> 

This of course would be different with the RFC you mentioned because
then they are not simply public mutable properties anymore but a real
method will be called that allows hooks. I wrote the above under the
assumption of:

    interface Example {

        final public DateTimeImmutable var $created;

    }

Where you end up not being able to hook into assignments and I am
against the introduction of such a feature. ;)

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92244 — Stanislav Malyshev — 2016-04-13T04:42:46+00:00

URL: https://externals.io/message/92084#92244 · In reply to: #92200

Hi!

> The *var* keyword is not going to be deprecated and its meaning is 
> currently kind of ambiguous. I tried to assign it a new meaning in
> the

Why is it ambiguous? It's pretty well defined, it's the same as public.

> class Foo {
> 
> val $x;
> 
> var $y;
> 
> val $z;
> 
> }
> 
> class Bar extends Foo {
> 
> var $x;
> 
> $y;
> 
> $z;
> 
> }

This looks very unobvious what is supposed to be going on here. I'd
much prefer to have every specification be explicit.

> The /z/ will stay a *val* (immutable) because its parent
> declaration is defined as such.
> 
> class Point {
> 
> final public float val $x = 0.0;

Wait, how is this different from a constant?

> The *final* keyword could be added via another RFC and it would
> have the same meaning as the *final* keyword for classes and
> methods: freeze the definition. This is why the *MutablePoint*
> results in fatal errors: it tries to redeclare /x/ and /y/ from
> *val* to *var* although they are *final*.

I'm not sure I understand what is the point in freezing the
definition. Could you explain use case for such thing?

> I think that Scala's *val*/*var* approach could really help us to
> make *var* usable again in a meaningful manner and it corresponds
> nicely to the concept of /value objects/ and related concepts with
> its naming scheme.

I'm not sure why var is unusable and why it is a worthy goal to make
it "usable again" - i.e. what exactly we are trying to achieve here?

If we want value objects, it *might* be valuable to have an object
that is readable but not writable from outside - even though it is
easily achievable right now by having public getters but no public
setters. But I'm not sure how "var" - or, for that matter, "final" -
fits the picture.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #92260 — Fleshgrinder — 2016-04-13T19:44:55+00:00

URL: https://externals.io/message/92084#92260 · In reply to: #92244

> Hi!
> 
> > […]
> 
> Why is it ambiguous? It's pretty well defined, it's the same as public.
> 

Well, no. The differences are well explained in the deprecation RFC:

https://wiki.php.net/rfc/var_deprecation

The documentation states the *var* is a substitute for *public* but in
reality it isn't. Also the name is ambiguous because /var/ does not mean
/public/. ;)


> > […]
> 
> This looks very unobvious what is supposed to be going on here. I'd
> much prefer to have every specification be explicit.
> 

This was less a proposal regarding how it will be in userland and more
about how the inheritance should be. I fully and completely agree with
you that the full definition should be restated if a property is going
to be redeclared in a child in userland. Either 1:1 or by changing what
is allowed to change. The above example in userland with a more
realistic example would be:

    class Foo {

        public float val $x;

        public float val $y;

    }

    class Bar extends Foo {

        public float var $x;

        public float var $y;

    }


> > […]
> 
> Wait, how is this different from a constant?
> 

It is different to a constant in many ways:

- It is bound to the instance and GCed with it.
- It can be set in the constructor.
- It can be cloned in __clone.

Of course there are other added benefits of properties like the ability
to contain object instances while not being reassignable but internally
mutable. Again, the example was more about how things should work and
not meant to be useful in any context. Here is a better example,
however, some compromises with non-final class and property visibility
to illustrate features:

    class Entity {

        final public int val $id;

        final public DateTimeImmutable val $created;

        final protected DateTimeImmutable var $changed;

        final protected OtherEntity var $other_entity;

        public function __construct(
            int $id,
            DateTimeImmutable $created,
            DateTimeImmutable $changed,
            OtherEntity $other_entity
        ) {
            assert(
                '$created <= $changed',
                '`created` cannot be less than `changed`'
            );
            $this->id = $id;
            $this->created = $created;
            $this->changed = $changed;
            $this->other_entity = $other_entity;
        }

        public function __clone() {
            $this->other_entity = clone $this->other_entity;
        }

        public function getChanged(): DateTimeImmutable {
            return $this->changed;
        }

        public function update(): void {
            $this->changed = new DateTimeImmutable;
        }


> > […]
> 
> I'm not sure I understand what is the point in freezing the
> definition. Could you explain use case for such thing?
> 

To avoid that child classes change the signature of a property from a
parent class if that is not desired. This is especially useful if you
intend to use public properties as part of your API or simply want to
update an existing anemic domain model by slowly adding the newly
proposed features here and to find bugs (e.g. assignments of wrong data
types, assignments at all, ...).

I am not saying that public properties should be part of an API. As I
wrote already and as Larry Garfield pointed out, having them as part of
the public API would mean that interfaces should be able to declare them
and that classes should be able to implement hooks. In other words:

https://wiki.php.net/rfc/propertygetsetsyntax-v1.2

@Larry: I know that I wrote that I don't get why you brought up that RFC
but now I know (and why I wrote a short addendum mail). ;)


> > […]
> 
> I'm not sure why var is unusable and why it is a worthy goal to make
> it "usable again" - i.e. what exactly we are trying to achieve here?
> 

For the reasons mentioned at the top and in the thread where we
discussed the deprecation. :)

> If we want value objects, it *might* be valuable to have an object
> that is readable but not writable from outside - even though it is
> easily achievable right now by having public getters but no public
> setters. But I'm not sure how "var" - or, for that matter, "final" -
> fits the picture.
> 

I hope I was able to explain the *var*, *val*, and *final* idea and I
encourage you to check out Java, Scala, Ceylon, ...

Immutable classes were discussed too in the not so far past and they
would add a lot of benefit but other benefits. The main advantage would
be that the objects could be considered safe at runtime for concurrency
(not a feature we currently have in PHP but still holds true) and would
not require one to take care of copy on write all the time.

    class ValueObject {

        private $value;

        public function __construct($value) {
            $this->value = $value;
        }

        public function doSomething() {
            $clone = clone $this;
            $clone->value = 'did something';
            return $clone;
        }

    }

Here is the related discussion that we should keep alive:

http://marc.info/?t=144766539400001&r=1&w=2

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92264 — Stanislav Malyshev — 2016-04-13T20:18:55+00:00

URL: https://externals.io/message/92084#92264 · In reply to: #92260

Hi!

> Well, no. The differences are well explained in the deprecation RFC:
> 
> https://wiki.php.net/rfc/var_deprecation

"var is currently a simple alias for public. "

> The documentation states the *var* is a substitute for *public* but in
> reality it isn't. 

How exactly it isn't? Except for "static"/"const" thing (which is really
a parser glitch and could be easily fixed if anybody cared) I don't see
a difference. Pretending like that static/const thing is a serious issue
that warrants some deep changes makes no sense to me - it's just a very
minor bug.

> It is different to a constant in many ways:
> 
> - It is bound to the instance and GCed with it.

Don't see why is it good or why should I care.For all I care it may
never be GCed at all (such as interned strings), and userland developer
should not be worrying about these details anyway.

> - It can be set in the constructor.
> - It can be cloned in __clone.

I find the idea that you have special methods that have magic about
variables not available to other methods rather unwise. And, you forgot
__wakeup for example, unless you're not going to ever serialize your
value object. And maybe other use cases. The point is, you are building
very complex mechanism here that is too magic, and it is going to break
in weird ways because it doesn't work like the rest of language works.

It also promotes bad design, as unless you want to track stack traces,
you'd be able to touch these vars only in magic methods, thus requiring
placing the code dealing with these vars in each of those methods and
only there - you can't put this code in a different method, for example,
because that method won't be magic. So, no refactoring for magic methods.

>         public function update(): void {
>             $this->changed = new DateTimeImmutable;
>         }

I don't see how $created works better than $changed. Moreover, it looks
rather strange that you have getter for $changed but not for $created.
To achieve consistency and avoid confusing people, you probably would
also have getCreated() anyway - which then makes "val" completely redundant.

> To avoid that child classes change the signature of a property from a
> parent class if that is not desired. This is especially useful if you
> intend to use public properties as part of your API or simply want to

I think that's not how it is done by all code I've seen so far - they
use getters instead. Now, we can say we want to get rid of getters, but
then I still don't see what use case final serves. I mean, "final is to
make things unchangeable" is not a use case - it just restating the same
thing in different words. The real question is *why* you need to make
them unchangeable?

> I am not saying that public properties should be part of an API. As I
> wrote already and as Larry Garfield pointed out, having them as part of
> the public API would mean that interfaces should be able to declare them
> and that classes should be able to implement hooks. In other words:

Exactly. So, unless we implement tons of other things, you can't really
use it, and even then it's unclear why you want to use it.

> For the reasons mentioned at the top and in the thread where we
> discussed the deprecation. :)

Well, I see no real reason there and deprecation failed, as it should
have. I don't exactly buy the argument of "we tried to deprecate var,
unsuccessfully, therefore there is a problem with it", and the only real
issue I have seen, as I mentioned above, is that minor static/const
glitch.

> I hope I was able to explain the *var*, *val*, and *final* idea and I
> encourage you to check out Java, Scala, Ceylon, ...

I know about existence of Java, Scala, etc. but "look at Java" is not a
very good explanation - Java is big, so it would be useful to clarify
what exactly I am supposed to be looking at and how it should convince
me with regard to PHP.
Also, I remind that both Java and Scala are compiled fully statically
strict typed languages, and PHP is not.

> would add a lot of benefit but other benefits. The main advantage would
> be that the objects could be considered safe at runtime for concurrency

Which is completely useless for PHP as it does not have
shared-environment concurrency and most likely never will. Also,
experience shows immutable value objects, while nice, does not solve
much of concurrency problems. Data structures are the real problem, and
immutable data structures are way harder to do. Anyway, this is
irrelevant for PHP in any case.

> (not a feature we currently have in PHP but still holds true) and would
> not require one to take care of copy on write all the time.

Err, how? The objects may be immutable but that says nothing of the
values within. So you'd still have to track them.
You could theoretically make some performance gains, maybe, by caching
property lookups, etc. for immutable objects, but I don't think you'd
gain too much compared to what we have now.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #92269 — Fleshgrinder — 2016-04-13T21:11:01+00:00

URL: https://externals.io/message/92084#92269 · In reply to: #92264

> How exactly it isn't? Except for "static"/"const" thing (which is really
> a parser glitch and could be easily fixed if anybody cared) I don't see
> a difference. Pretending like that static/const thing is a serious issue
> that warrants some deep changes makes no sense to me - it's just a very
> minor bug.
> 

Possible approach, yes. Still a huge inconsistency with function
declarations and their access modifiers (*var function*?!?). Just look
at the special definitions in the Bison file on how it is currently
handled. I know that the two of us have a different meaning about this
topic but in case we extend access modifiers inconsistency grows.

var class ?!?
var function ?!?
var const ?!?
var static ?!?

> > […]
> 
> Don't see why is it good or why should I care.For all I care it may
> never be GCed at all (such as interned strings), and userland developer
> should not be worrying about these details anyway.
> 

I did not say that a userland developer should care I only stated that
it is one difference between a constant and a final property. ;)

> > […]
> 
> I find the idea that you have special methods that have magic about
> variables not available to other methods rather unwise. And, you forgot
> __wakeup for example, unless you're not going to ever serialize your
> value object. And maybe other use cases. The point is, you are building
> very complex mechanism here that is too magic, and it is going to break
> in weird ways because it doesn't work like the rest of language works.
> 

This thread is meant to find out where, how, when support is needed and
you are absolutely right that *__wakeup* needs support too. I am sure we
overlooked others yet. I did not claim to cover all edge cases. ;)

> It also promotes bad design, as unless you want to track stack traces,
> you'd be able to touch these vars only in magic methods, thus requiring
> placing the code dealing with these vars in each of those methods and
> only there - you can't put this code in a different method, for example,
> because that method won't be magic. So, no refactoring for magic methods.
> 

That is exactly the point of it. Limiting interaction, limiting sources
of bugs. Just read why others want to have them instead of only taking
my word (and bad examples) for it.

> > […]
> 
> I don't see how $created works better than $changed. Moreover, it looks
> rather strange that you have getter for $changed but not for $created.
> To achieve consistency and avoid confusing people, you probably would
> also have getCreated() anyway - which then makes "val" completely redundant.
> 

It is an example to illustrate the functionality and not meant to be a
blueprint for all userland implementations that are yet to be written
till the end of time. It is contrived, no argument there.

> > […]
> 
> I think that's not how it is done by all code I've seen so far - they
> use getters instead. Now, we can say we want to get rid of getters, but
> then I still don't see what use case final serves. I mean, "final is to
> make things unchangeable" is not a use case - it just restating the same
> thing in different words. The real question is *why* you need to make
> them unchangeable?
> 

Because you want to let child classes read from the property without
calling methods while making sure that they cannot change it in any way
(also called *readonly* in C#). This is particularly important in case
of object getters because a child class cannot trust the parent class
that an object retrieved from that getter is always the same instance.
This is why it is recommended to assign the result of such a call in a
method in various highly regarded literature (e.g. Steve McConnell Code
Complete comes to my mind).

With a *final val* property the child can trust the parent again. I know
that the situation is often different in PHP because the source is
always readily available. However, an API user should not need to dig
into the source code, an API user should be able to understand, use, and
trust other code simply through peeking at definitions and signatures.
Before you start, I am not claiming that this is always possible nor
that this is always desired, always needs to be like that, or anything
else. It is just something that is nice to achieve and it allows control
over what is going to happen at runtime and how people will be able to
interact with code that was written by you for them.

> > […]
> 
> Exactly. So, unless we implement tons of other things, you can't really
> use it, and even then it's unclear why you want to use it.
> 

Public properties are available yet and used heavily in many projects to
create shitty anemic domain model for, you guessed it, performance
reasons. Providing a *final* keyword will not change that. Larry just
brought up the discussion regarding properties in interfaces, that's it
and nothing more.

> > […]
> 
> Well, I see no real reason there and deprecation failed, as it should
> have. I don't exactly buy the argument of "we tried to deprecate var,
> unsuccessfully, therefore there is a problem with it", and the only real
> issue I have seen, as I mentioned above, is that minor static/const
> glitch.
> 

I know that it might look like that but I still think that its usage is
ambiguous and inconsistent and all explanation attempts failed in the
old thread, in the RFC, and they will fail here. I do not know any other
way in that I could explain it to you so that you agree. However, I do
not know of I have to be that person who does that. It's fine for me if
you are against it or me. :)

> > […]
> 
> I know about existence of Java, Scala, etc. but "look at Java" is not a
> very good explanation - Java is big, so it would be useful to clarify
> what exactly I am supposed to be looking at and how it should convince
> me with regard to PHP.
> Also, I remind that both Java and Scala are compiled fully statically
> strict typed languages, and PHP is not.
> 

Really? You should look at *final*, *val*, and *var* -- what are we
discussing here?

https://en.wikipedia.org/wiki/Final_%28Java%29

http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html

http://stackoverflow.com/a/1327549/1251219

> > […]
> 
> Which is completely useless for PHP as it does not have
> shared-environment concurrency and most likely never will. Also,
> experience shows immutable value objects, while nice, does not solve
> much of concurrency problems. Data structures are the real problem, and
> immutable data structures are way harder to do. Anyway, this is
> irrelevant for PHP in any case.
> 

I said so and it was only an example. However, people are actually
trying (pthreads? anyone?) to bring this to PHP so never say never. ;)

> > […]
> 
> Err, how? The objects may be immutable but that says nothing of the
> values within. So you'd still have to track them.
> You could theoretically make some performance gains, maybe, by caching
> property lookups, etc. for immutable objects, but I don't think you'd
> gain too much compared to what we have now.
> 

You gain a shitload of DRY in userland. This is more than worthwhile.
You might react allergic towards syntactic sugar but it can be extremely
nice. But let's not get off-topic any further here (feel free to open
separate threads or resurrect the old one, I will reply).

-- 
Richard "Fleshgrinder" Fussenegger

---

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