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 >