Hey guys :)

# Abstract Classes
Establishing a contract that any child class of an abstract class has to
be immutable is a totally valid use case in my opinion and it aids
consistency. Otherwise we have the same situation as with final which I
never understood. Actually, even interfaces could benefit from this
modifier.

# Clone
What Larry illustrated is exactly how I build immutable value objects
right now too. However, cloning as we have it is not what we want, we
want a mutable clone while cloning is not allowed to the outside world.
It simply makes no sense to clone a value object for the same reason as
it makes no sense to clone a string.

On a side note, I always change the visibility of the __clone callback
in my value objects to protected/private and disable cloning for the
outside world this way. Cloning a value object is a programming error
and not something that should be catchable and recoverable.

I see various ways to approach this topic and did not include anything
in the previous message because I wanted to think a bit more about it.

## Proposal 1
My first proposal would be to allow mutation within the class itself but
directly creating a copy to ensure integrity and immutability of the
current instance.

  final immutable class ValueObject {

    public $value;

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

      return $this;
    }

  }

The write is happening in a compatible context (within the class),
however, the $this variable contains a copy of the original now with the
changed value instead of the actual instance. Not returning it means
that it is simply lost and the state of the current instance is never
touched.

  public function withValue($value) {
    if ($value !== null) {
      $this->value = $value;
    }

    return $this;
  }

If $value is null the same instance is returned as is since no write
happened.

The only thing I do not like about this approach is that it is implicit
and not explicit. At the same time it avoids all kinds of problems since
the engine handles everything for you and it requires less typing.

## Proposal 2
The __clone callback returns an instance that is mutable within the
class itself but not from the outside. This is pretty much like the
first proposal but making the clone operation explicit. Note that any
write to the current instance would always be an error here.

  public function withValue($value) {
    if ($value !== null) {
      $copy = clone $this;
      $copy->value = $value;

      return $copy;
    }

    return $this;
  }

Significantly more typing and of course a source of error because the
engine does not take care of the work for you.

# Arrays and Resources
This definitely needs clarification in the RFC since it is a very
important restriction.

# Flyweight
Thinking about it, it's actually possible with the current
implementation to create it by simply leaving of the modifier from the
class.

  final class Flyweight {

    private static $instances = [];

    public immutable $value;

  }

Hence, forget about the remark.

# Dynamic Properties
Should definitely error on write and it should be explained in the RFC.

-- 
Richard "Fleshgrinder" Fussenegger

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to