Mathieu Rochette wrote on 16/11/2015 10:00:
Would it be allowed to assign non immutable types to properties of an immutable class ?

I think this is the trickiest part of trying to enforce immutability: nesting. Consider the following:

// Basic properties
$my_immutable_object->foo = 42;
$my_immutable_object->foo++;

// Nested object - implicitly immutable? required to be explicitly immutable?
$my_immutable_object->bar->something = 42;
$my_immutable_object->bar->setSomething(42);

// Array access - no idea how this should work
$my_immutable_object->quux[0] = 42;
$my_immutable_object->quux[] = 'Hello';
$my_immutable_object->quux['World'][0]['X'] = 'A';


The other problem is that to be useful, certain functions usually need to be able to mutate the state of objects which are officially immutable. For instance, implementations of PSR-7 need a set of copy constructors for the withX methods. You could do this using the suggested rule that immutability applies only to non-null properties, and manually populate every property of an empty instance, but it's much more efficient to "clone $this" and then change the one property that needs to be different.

For this particular example, you could write quite a nice implementation by "freezing" the instance once it's initialised:

// example plucked from https://github.com/guzzle/psr7/blob/master/src/Request.php#L101
    public function withMethod($method)
    {
// The method starts by making a mutable clone of the immutable $this
        $new = clone $this;
        $new->method = strtoupper($method);

        # SUGGESTED ADDITION: new keyword to set an object to be immutable
        freeze $new;
// After this point, nothing should be able to mutate the new object, only clone it

        return $new;
    }


The freeze operation could perhaps be recursive, or perhaps it could work like "clone", with an "__freeze" method responsible for freezing nested objects as necessary. The ability to freeze an array would also be useful in that case...

I realise this is a lot more complex than the original suggestion, but I think something of this level of detail is needed to make it useful.

Regards,
--
Rowan Collins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to