Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:89259 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 71309 invoked from network); 17 Nov 2015 08:12:45 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Nov 2015 08:12:45 -0000 Authentication-Results: pb1.pair.com smtp.mail=lisachenko.it@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=lisachenko.it@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.170 as permitted sender) X-PHP-List-Original-Sender: lisachenko.it@gmail.com X-Host-Fingerprint: 209.85.217.170 mail-lb0-f170.google.com Received: from [209.85.217.170] ([209.85.217.170:36022] helo=mail-lb0-f170.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0E/71-57591-B71EA465 for ; Tue, 17 Nov 2015 03:12:43 -0500 Received: by lbblt2 with SMTP id lt2so698045lbb.3 for ; Tue, 17 Nov 2015 00:12:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=uC/e2FIx3lh5T/w4rFX/7riaibEc2WEvq5T9ytoNmro=; b=n/j9/NJOJsJXetcwB1E3raRKaj4wJr4wRkij8EDRLYl2Cbo1YJW9ZXKH88D7P9l1Xg SXvgUWQMS+1Jurrd8bxL+N3F/5pwt8lk95xylWse32n6UBnahryT9c1I1KsdHKokhJT0 rxOonrR1H5ZoVA90k5mUWctEkvmq3S2ECrJ2HkFgJagysHcRmmAAlC/iJE2gQMRErfN4 y3r6tTA76NG7emhf4y/gRIT6iICugnh1MV4dPetMazr3vqhIPs+MabJjqyVrVi+Xj3NQ UndD5f3hp8km2bVq8lOAZjy1tzQdRsuHs7SjH7NYXufDodLdYnf66/0J7uANCTOaQkAi tzSw== MIME-Version: 1.0 X-Received: by 10.112.236.67 with SMTP id us3mr1734424lbc.64.1447747958908; Tue, 17 Nov 2015 00:12:38 -0800 (PST) Received: by 10.25.42.15 with HTTP; Tue, 17 Nov 2015 00:12:38 -0800 (PST) In-Reply-To: References: Date: Tue, 17 Nov 2015 11:12:38 +0300 Message-ID: To: Chris Riley Cc: Andrea Faulds , PHP internals list Content-Type: multipart/alternative; boundary=001a11c323f6d0b1eb0524b816b0 Subject: Re: [PHP-DEV] Immutable modifier From: lisachenko.it@gmail.com (Alexander Lisachenko) --001a11c323f6d0b1eb0524b816b0 Content-Type: text/plain; charset=UTF-8 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 : > On Tue, 17 Nov 2015, 02:07 Andrea Faulds 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:// ajf.me/ > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: 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 > --001a11c323f6d0b1eb0524b816b0--