On 4/13/2016 6:42 AM, Stanislav Malyshev wrote:
> 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.
> 

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/. ;)

On 4/13/2016 6:42 AM, Stanislav Malyshev wrote:
>> 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.
> 

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;

    }

On 4/13/2016 6:42 AM, Stanislav Malyshev wrote:
>> 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?
> 

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;
        }

On 4/13/2016 6:42 AM, Stanislav Malyshev wrote:
>> 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?
> 

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

On 4/13/2016 6:42 AM, Stanislav Malyshev wrote:
>> 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?
> 

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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to