Hello, internals!

We discussed this topic early, see this thread:
http://www.serverphorums.com/read.php?7,1123371,1124223 for any additional
thoughts and ideas. I want to attach a link to the Java draft of partial
immutability of objects:
http://cr.openjdk.java.net/~jrose/values/values-0.html, it's pretty
interesting and can be applied for PHP too.

I very like the whole idea of having native immutability for objects and
see a many cases where it can be applied.

I'm thinking about immutability for objects as passing variables as a copy
by value, not by reference. Const keyword can be used for that:

class Foo {
     public static function bar(const Baz $object) {  // Require an
instance of Baz to be passed as a copy, not a reference
         $object->test = '12345'; // Will throw an exception, because for
immutable object property fetching for writing is not allowed
         $object = 12345; // Will throw an exception, immutable variable
can not modified

         $myObject = $object; // Create our local copy of immutable object,
this will be a full copy (clone)
         $myObject->test = '456'; // OK
         echo $myObject->test, ' original is ', $object->test; // Will
output: '456 original is foo'
     }
}

$obj = new Baz; // Our local instance, #1
$obj->test = 'foo';
Foo::bar($obj); // Method requires immutability, so a new copy of $obj will
be created before passing value to the method

echo $obj->test; // Outputs 'foo'

Here, an original object will be preserved in any case, because a copy will
be used (probably, via cloning) and engine will check some restrictions to
keep variable immutability.

Some more code examples:

function foo() {
    const $bar = new stdClass; // We use const keyword with variable name
to declare it immutable
    $bar = 1; // Will throw an exception, because $bar is immutable const
variable
    $bar->test = 123; // Will throw an exception, because for immutable
variable which is object property fetch for writing is not allowed

    const $immutableArray = [1, 2, 3];
    $immutableArray[] = 4; // Immutable array can not be modified, only
read operation is supported

    $mutableArray = $immutableArray; // If we make a copy of variable
without const, it can be changed later via Copy-on-Write
    $mutableArray[] = 5; // OK, local copy is used
}

Function or methods can declare a return result to be immutable by adding a
"const" keyword into the declaration:

const function foo() : Baz // declare our function to return an immutable
copy of object
{
    $object = new Baz;
    $object->test = 456;
    return $object;
}

$value = foo(); // Will throw an exception, immutable return result from
the function can be assigned only to the immutable variable
const $immutableValue = foo(); // OK, immutable result is stored in the
immutable variable

ReflectionParameter, ReflectionFunctionAbstract can have an additional
methods: ReflectionParameter->isImmutable() or
RelectionParameter->isConst();
ReflectionFunctionAbstract->returnsImmutableValue()



2015-11-17 10:18 GMT+03:00 Chris Riley <t.carn...@gmail.com>:

> On Tue, 17 Nov 2015, 02:07 Andrea Faulds <a...@ajf.me> wrote:
>
> Hi,
>
> Chris Riley wrote:
> >
> > There has been a lot of interest recently (eg psr-7) in immutable data.
> I'm
> > considering putting an RFC together to add language support for
> immutables:
> >
>
> I wonder if immutable classes are really the right way to go. Immutable
> reference types with manual copying are somewhat alien to PHP: instead,
> the language has used copy-on-write mutable value types for arrays and
> strings, and prior to PHP 5, objects.
>
> Copy-on-write value types have all the benefits immutable types do. They
> can't be mutated at a distance unless you make a reference to them,
> trees made of them can be compared for equality with just ===, etc.
>
> But they also have benefits that immutable types lack. They're easier to
> work with, because you can directly mutate them like everyone's used to
> doing: no messing around with withFooBar() and withoutFooBar(), you just
> set foobar or remove it directly. And PHP handles the duplication of
> objects for you implicitly, so there's far less code to write.
>
> Unfortunately, PHP 5 got rid of PHP 4's value type objects and replaced
> them with reference type objects. But we could always introduce a way to
> get value type objects again. How about a `struct` keyword? It would be
> equivalent to `class`, but produce a value type rather than a reference
> type.
>
> Any thoughts?
>
> Thanks.
> --
> Andrea Faulds
> http:// <http://ajf.me/>ajf.me/ <http://ajf.me/>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http:// <http://www.php.net/unsub.php>www.php.net
> <http://www.php.net/unsub.php>/ <http://www.php.net/unsub.php>unsub.php
> <http://www.php.net/unsub.php>
>
>
> My main motivation for this was for event objects when doing event sourcing
> - they are by definition unchangeable after creation. That said,
> considering the wider use case there does seem to be a need to emulate the
> with* functions.
>
> One option would be to hide the messy constructor call within user defined
> methods, but that would add a lot of boilerplate - something I was wanting
> to reduce not increase.
>
> I can't think of a clean easy way to add with* functionality at a language
> level without even more magic (parameter skipping?)
>
> As for setter injection - my initial proposal would support that - a
> property declared immutable allows itself to be set - once.
>
> If someone can give my wiki account rfc karma I can write this up so far
> too help focus discussion.
>
> ~C
>

Reply via email to