Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:95725 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 83461 invoked from network); 7 Sep 2016 09:35:26 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Sep 2016 09:35:26 -0000 Authentication-Results: pb1.pair.com smtp.mail=marijic.silvio@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=marijic.silvio@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.43 as permitted sender) X-PHP-List-Original-Sender: marijic.silvio@gmail.com X-Host-Fingerprint: 209.85.214.43 mail-it0-f43.google.com Received: from [209.85.214.43] ([209.85.214.43:38505] helo=mail-it0-f43.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id BA/6A-18051-D5FDFC75 for ; Wed, 07 Sep 2016 05:35:25 -0400 Received: by mail-it0-f43.google.com with SMTP id c198so11526905ith.1 for ; Wed, 07 Sep 2016 02:35:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=hoPfQ7Q7bRiQEhHuRdUF7jBr6PK9W/YgmZ7lU77JLyM=; b=w0bLYSTymDMNZTvZbHAJxBW3hVUc3YVcQx5u16deto4v/Nu3llYwdrSsQ7l/kT319S tWgllaozty31w0f2QezwHckca5VRhzRGHB5gkVwICAXIJIdBogorlWc9nd/qMxY8+9TR dI101Sbc+vASwF5zceeR3ZJYHsJX6CqlVqrDup1TgNbyKXRM2LeUGpuJ7UIYv+XeQKu3 CbsDLWy+95XmyAJKt+ReiEM2LQQppkoxUD0/l62KERmUle/6F8oBTxFU7ajIwozU+Nz7 7Hj9Gjntgr4RYns/2KmRpGPWMEgv0xdZ2Ou7JtZn8ATQKe9byWpYuwla9NjWRE5QdUHP a5Eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=hoPfQ7Q7bRiQEhHuRdUF7jBr6PK9W/YgmZ7lU77JLyM=; b=Mxab9Fnl8KhcM/lIWe+X+dLFmoRF5QDUCh5y3Ko3QOquMdc9s64/e8rXu8jfCurU1G cfC4IRhc8JBT2owAAiR8zZVFeXCqen2wplfrA4LwtMJFoZPII9P5JWkFF6PtIU0KfgSd h3KqBFY0aMVo/ugHjkyKYQ3rEGswt3lCziPAg7sUBIce3Qx8yUxaZiwBQQQ4wGsgWGfS 7JbBpggflvLcVgQPTsMGVmdH9mmJjJ2WNSXQA962t/enhSEzFtxBRcwtPhI8necLLtdr eUtV6NOpJnMDbuipV6dOPdGMY/PCLtlgMf6+okxsbSGZSbFSZkpN6MlZMTYCP+PFR5vd VSCA== X-Gm-Message-State: AE9vXwNS+FRtRdkgMLLO5YPuC4cT32qT1P8XCBdJ+r6EZBTAuGBXDzLfzaq1u8zUoiq57mUQGEk8bTJZnV1JZw== X-Received: by 10.36.152.5 with SMTP id n5mr4677336itd.79.1473240922761; Wed, 07 Sep 2016 02:35:22 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.237.74 with HTTP; Wed, 7 Sep 2016 02:35:21 -0700 (PDT) In-Reply-To: References: <0e71d28e-1d64-5372-b58d-e54c7afae3b8@fleshgrinder.com> <642a6e78-90ea-cbf0-ec1c-376c24e568c5@fleshgrinder.com> <0800a5ca-3d14-c541-1a1a-2574ec802b8c@fleshgrinder.com> <83fa661e-2d3d-6548-a506-fb969be31c0e@garfieldtech.com> <69D0D60B-3D42-4228-8156-F9E6AFEDF72B@koalephant.com> Date: Wed, 7 Sep 2016 11:35:21 +0200 Message-ID: To: Stephen Reay Cc: PHP Internals List Content-Type: multipart/alternative; boundary=94eb2c05f7f8deaf5a053be7a188 Subject: Re: [PHP-DEV] RFC - Immutable classes From: marijic.silvio@gmail.com (=?UTF-8?Q?Silvio_Mariji=C4=87?=) --94eb2c05f7f8deaf5a053be7a188 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable And also Fleshgrinder made a good point about comparing two immutable objects. They should be compared based on value, not on identity. 2016-09-07 11:28 GMT+02:00 Silvio Mariji=C4=87 : > Hi Stephen, > > Cloning is disabled at the moment in implementation because you would end > up with a object that you can not change, so you have no use of that. I'l= l > change that as soon as we find some good solution for handling that. Your > example is not really clear to me. At what point we should unlock/lock > object based on your example? > > DateTimeImmutable does not prevent cloning because immutability is > achieved by encapsulation, and we want to get rid of the need of > encapsulation in our implementation of immutable objects. > > Best, > Silvio. > > 2016-09-07 11:05 GMT+02:00 Stephen Reay : > >> (Sorry for any dupes, sent from wrong address originally) >> >> From a developer point of view, I would suggest that a feature should ai= m >> to be as clear to understand with as little =E2=80=9Cmagic" as possible. >> >> >> If the goal of an immutable class is to allow public properties to be >> made read-only, my expectation would be that: >> >> - write access to any public property from outside class context, is an >> error. >> >> This seems to be pretty much accepted by everyone >> >> >> - clone still works as expected >> >> There has been some suggestion that clone $immutableObj should not be >> allowed. Unless there is some specific language/engine gain by that, wha= t >> is the point of having this behaviour? >> Existing built-in immutable classes (like DateTimeImmutable) do not >> prevent cloning, so why should this? >> >> - regular cloning from within class method(s) is the suggested way to >> provide =E2=80=9Ccreate a copy of the object with a new value=E2=80=9D f= unctionality. >> >> This example was given before, effectively: >> >> public function withValue($val) { >> $clone =3D clone $this; >> $clone->val =3D $val; >> >> return $clone; >> } >> >> >> >> >> >> > On 7 Sep 2016, at 13:57, Micha=C5=82 Brzuchalski >> wrote: >> > >> > 06.09.2016 9:13 PM "Fleshgrinder" napisa=C5=82(= a): >> >> >> >> I understand the concerns of all of you very well and it's nice to se= e >> a >> >> discussion around this topic. Fun fact, we are not the only ones with >> >> these issues: https://github.com/dotnet/roslyn/issues/159 >> >> >> >> On 9/6/2016 6:01 PM, Larry Garfield wrote: >> >>> How big of a need is it to allow returning $this instead of $clone, >> >>> and/or can that be internalized somehow as well? With copy-on-write= , >> >>> is that really an issue beyond a micro-optimization? >> >> >> >> I asked the same question before because I am also unable to answer >> this >> >> question regarding the engine. >> >> >> >> However, for me it is more than micro-optimization, it is about >> identity. >> >> >> >> final class Immutable { >> >> // ... the usual ... >> >> public function withValue($value) { >> >> $clone =3D clone $this; >> >> $clone->value =3D $value; >> >> return $clone; >> >> } >> >> } >> >> >> >> $red =3D new Immutable('red'); >> >> $still_red =3D $red->withValue('red'); >> >> >> >> var_dump($red =3D=3D=3D $still_red); // bool(false) >> >> >> >> This is a problem in terms of value objects and PHP still does not >> allow >> >> us operator overloading. A circumstance that I definitely want to >> >> address in the near future. >> >> >> >> But the keyword copy-on-write leads me to yet another proposal, >> actually >> >> your input led me to two new proposals. >> >> >> >> # Copy-on-Write (CoW) >> >> Why are we even bothering on finding ways on making it hard for >> >> developers while the solution to our problem is directly in front of >> us: >> >> PHP Strings! >> >> >> > >> > AFAIK CoW in case of objects would be impossible to implement. >> > >> >> Every place in a PHP program refers to the same string if that string >> is >> >> the same string. In the second someone mutates that string in any way >> >> she gets her own mutated reference to that string. >> >> >> >> That's exactly how we could deal with immutable objects. Developers d= o >> >> not need to take care of anything, they just write totally normal >> >> objects and the engine takes care of everything. >> >> >> >> This approach also has the advantage that the return value of any >> method >> >> is (as always) up to the developers. >> >> >> >> (Cloning is disabled and results in an error as is because it makes n= o >> >> sense at all.) >> >> >> >> # Identity >> >> This directly leads to the second part of my thoughts and I already >> >> touched that topic: identity. If we have two strings their binary >> >> representation is always the same: >> >> >> >> var_dump('string' =3D=3D=3D 'string'); // bool(true) >> >> >> >> This is the exact behavior one wants for value objects too. Hence, >> >> immutable objects should have this behavior since they identify >> >> themselves by their values and not through instances. If I create two >> >> instances of Money with the amount 10 and the Currency EUR then they >> are >> >> always the same, no matter what. This would also mean that no develop= er >> >> ever needs to check if the new value is the same as the existing one, >> >> nor does anyone ever has to implement the flyweight pattern for >> >> immutable objects. >> >> >> >> A last very important attribute is that it does not matter in which >> >> thread an immutable value object is created because it always has the >> >> same identity regardless of it. >> >> >> >> This could easily be achieved by overwriting the object hashes >> >> (spl_object_hash) with something that hashes based on the values, and >> >> predictably across threads (UUIDs?). >> >> >> >> # Full Example >> >> > >> >> >> final immutable class ValueObject { >> >> >> >> public $value; >> >> >> >> public function __construct($value) { >> >> $this->value =3D $value; >> >> } >> >> >> >> public function withValue($value) { >> >> $this->value =3D $value; >> >> } >> >> >> >> } >> >> >> >> class A { >> >> >> >> public $vo; >> >> >> >> public function __construct(ValueObject $vo) { >> >> $this->vo =3D $vo; >> >> } >> >> >> >> } >> >> >> >> class B { >> >> >> >> public $vo; >> >> >> >> public function __construct(ValueObject $vo) { >> >> $this->vo =3D $vo; >> >> } >> >> >> >> } >> >> >> >> $vo =3D new ValueObject(1); >> >> >> >> $a =3D new A($vo); >> >> $b =3D new B($vo); >> >> >> >> var_dump($a->vo =3D=3D=3D $b->vo); // bool(true) >> >> >> >> $a->vo->withValue(2); >> >> >> >> var_dump($a->vo =3D=3D=3D $b->vo); // bool(false) >> >> >> >> $a->vo->withValue(1); >> >> >> >> var_dump($a->vo =3D=3D=3D $b->vo); // bool(true) >> >> >> >> // :) >> >> >> >> ?> >> >> >> >> -- >> >> Richard "Fleshgrinder" Fussenegger >> >> >> >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> > > > -- > Silvio Mariji=C4=87 > Software Engineer > 2e Systems > --=20 Silvio Mariji=C4=87 Software Engineer 2e Systems --94eb2c05f7f8deaf5a053be7a188--