Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81554 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 68189 invoked from network); 2 Feb 2015 07:31:55 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Feb 2015 07:31:55 -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 74.125.82.43 as permitted sender) X-PHP-List-Original-Sender: lisachenko.it@gmail.com X-Host-Fingerprint: 74.125.82.43 mail-wg0-f43.google.com Received: from [74.125.82.43] ([74.125.82.43:36860] helo=mail-wg0-f43.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A2/00-02376-BE72FC45 for ; Mon, 02 Feb 2015 02:31:55 -0500 Received: by mail-wg0-f43.google.com with SMTP id y19so37020989wgg.2 for ; Sun, 01 Feb 2015 23:31:51 -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=w/yMz1qA0oUhOUKBvnjPQlwCZPpLaQouUh6qDlbPQlQ=; b=AMY+nUo+AHsHoXQTEMmPGgqLwJy5+ayPc218GND3S3hl5PHMytVs663QQXyGd274Kr MsEKXeeGetITaKxr78qvAqKWJnO2eq78yuBUbW9Z4YZJi8zfRWSmZWUpruR6gsqNUqIV yfL5MJpAWXfi6cseBoK4ke3kvgQp89ztFxc9YdGSymUEItVn1w5r6CcqtIER6Aumj66i sx2irC+c3DM89m6LEtsWjK99Tmkeca7LuCgDmA+nTk5FZse3WUCLkENAPCuHr1rJyr9C xcfvOD4aTiyZ1BpnB94VRNhiyQ3rBG9/0oNmsuQSlyCQHbc3zg+TYcnWwQt+6QE6HqZP OZTw== MIME-Version: 1.0 X-Received: by 10.180.84.162 with SMTP id a2mr18132406wiz.47.1422862311713; Sun, 01 Feb 2015 23:31:51 -0800 (PST) Received: by 10.194.154.229 with HTTP; Sun, 1 Feb 2015 23:31:51 -0800 (PST) In-Reply-To: <61B0AAF8-9A3E-4889-917E-42AA48D946FA@ajf.me> References: <54CBC804.7050706@gmail.com> <54CD7668.30301@garfieldtech.com> <61B0AAF8-9A3E-4889-917E-42AA48D946FA@ajf.me> Date: Mon, 2 Feb 2015 10:31:51 +0300 Message-ID: To: Andrea Faulds Cc: Larry Garfield , PHP internals list Content-Type: multipart/alternative; boundary=f46d04427194a7728a050e15f28e Subject: Re: [PHP-DEV] [RFC] Immutable variables and objects From: lisachenko.it@gmail.com (Alexander Lisachenko) --f46d04427194a7728a050e15f28e Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hello, internals! 2015-02-01 4:01 GMT+03:00 Andrea Faulds : > I think having some means to create value type classes (i.e. PHP 4-style > classes) would be beneficial. These classes would have the same always-co= py > or copy-on-write behaviour that PHP=E2=80=99s scalar types and arrays hav= e. They=E2=80=99d > be performant compared to immutable classes like PSR-7=E2=80=99s, because > operations mutate the value in-place if possible, rather than creating a > new class. They=E2=80=99d also be nicer to use, because you can change th= e value > imperatively rather than having to chain together return values. But you > keep the main advantages of immutable types: no spooky action at a > distance, no explicit copying needed. Agree in that point with you, this can be a good instrument if implemented in PHP. I see a good point in it by using this with interfaces and "const" modifier for parameters: class Foo { public function bar(const Baz $object); // Require an instance to be passed as copy } This should be used as weakly immutability for places where changes of object is not expected. However, we can call methods on $objet, e.g. setters. The same will be useful for simple object variables: const $object =3D new stdClass; $object =3D 123; // Exception, can not change const variable $object->field =3D 456; // Exception, can not change public properties for const objects $anotherObject =3D $object; // Copy on write $anotherObject->field =3D 123; // ok to change local copy However, we should not worry about setters (if present): class MutableObject { public $field =3D 42; public function setField(const integer $newValue) { $this->field =3D $newValue; } } // let's create immutable object instance for that const $instance =3D new MutableObject(); $instance->field =3D 56; // Exception, can not change public properties for const objects // BUT, no checks for setters $instance->setField(56); echo $instance->field; // outputs 56 I think temporary immutability for objects can solve a lot of extra checks. For example, my previous code allows to drop extra getters ($instance->getField()) for simple classes, when we just want to work on our local copy of object in read-only mode. With this feature DateTimeImmutable functionality can be implemented like that: const $now =3D new DateTime(); $future =3D $now; // Copy on write $future->modify('+1 day'); // only $future variable is modified echo $now->format(DATE_RFC822); // unchanged On 1 Feb 2015, at 00:55, Stanislav Malyshev wrote: > For all this, I'd like to ask - why? Immutable object are very useful in > concurrency applications, since they allow to avoid expensive > synchronization costs and make it much easier to reason about system's > state (which is arguably impossible to predict with mutable objects in a > parallel system). But PHP has no parallelism. So which benefit would > that provide? If you want an immutable object, just make all properties > protected and provide getters but not setters. This is easily doable > without any keywords. Yes, parallelism is not present in PHP (except pthreads extension), so this requirement for temporary immutability of variables is less than in multi-threaded applications with IPC. But I think that main advantage of this modifier (immutable) is to add extra protection and assumption for developers to bypass extra getters (sorry, Doctrine) and to allow more safer code. Passing a copy of object (should this be deeper clone or not?) as an argument to the function is nice feature too, IMO. We *explicitly* mark an argument as immutable for method body, so no direct changes will be performed on this instance and no overhead for calling getters. Should I try to write an RFC for that? --f46d04427194a7728a050e15f28e--