Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:95723 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 79564 invoked from network); 7 Sep 2016 09:28:43 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Sep 2016 09:28:43 -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.52 as permitted sender) X-PHP-List-Original-Sender: marijic.silvio@gmail.com X-Host-Fingerprint: 209.85.214.52 mail-it0-f52.google.com Received: from [209.85.214.52] ([209.85.214.52:37109] helo=mail-it0-f52.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id AA/B9-18051-8CDDFC75 for ; Wed, 07 Sep 2016 05:28:41 -0400 Received: by mail-it0-f52.google.com with SMTP id e124so11273522ith.0 for ; Wed, 07 Sep 2016 02:28:40 -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=2Ir54D26GuJV6BaVoq1eVRpkrJhdNBBTsP72ofMKpzQ=; b=0KffaRANL6PNxvlmyfCGhlm9RzJ7ijJCzgDZFoecZcIf8oRKOZ0ofxjPCVLh9t2NO9 +r824tConToi08XadYCFWDEkTwRGsYwZCMaybrPoOpV5D33xN+X0P9F/+JfhlTR8yPIa +ZkmXgHamf7isOsA0YPZTue0B3lofkT3eTVJ+j9Qpj+/fyZkwopvgUnLcvDT7HJqdxxX QzJYtJS9T9pdzcvFCtatPwKwHwfFMhMU9ZLTq3lytZ3SheWGNtZGcnHPPq9Krf2X1JSl Qi6pbplY2uaceQtFNGLRhLB7bR/YWrtfokSU8fUQcl68uQRLFQvDipN0nyPF+LmSFmOs QROQ== 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=2Ir54D26GuJV6BaVoq1eVRpkrJhdNBBTsP72ofMKpzQ=; b=HNx5fixrwnNOOUnhawZ+zwXFo4Ndl5En0YgHP7pFmzMAPD1lsc/bpC6x4xyF5aWFF3 3qz57rWLmoqsY4BP6Uzr+ZTkiUyS7IRMX5dctLL6W71Kaf5tG+N5dyGi5iNWTQun+Kmj lJtZwmZgAMqbZbg+Rkul52BFFxCUemc9y6T5mJgVqGkFyNOp4qWbN6kwB5GOMyUByIq2 OnueNE+PTvuJP+ZvphXcjZ4zfi1qnUsbShofC2Hgj69lhf/5+lkHtrw3/bBdwssuNd0e +S7A3QJbKPPn/+YRTgS2/qX1Vwv45NYaulQHIO5d49BoDxi76EDC5lSWhnWd+TzLxFwo rcXw== X-Gm-Message-State: AE9vXwO+V5WJUS+QwwON6kC9OdiIa93vB9t9T+LJGl8oUKmatPPlyeDRWzApkjp9S0l2phYy7YDSROUddqACwQ== X-Received: by 10.36.53.83 with SMTP id k80mr4767901ita.59.1473240517399; Wed, 07 Sep 2016 02:28:37 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.237.74 with HTTP; Wed, 7 Sep 2016 02:28:36 -0700 (PDT) In-Reply-To: <69D0D60B-3D42-4228-8156-F9E6AFEDF72B@koalephant.com> 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:28:36 +0200 Message-ID: To: Stephen Reay Cc: PHP Internals List Content-Type: multipart/alternative; boundary=001a114a9622b5584c053be789d0 Subject: Re: [PHP-DEV] RFC - Immutable classes From: marijic.silvio@gmail.com (=?UTF-8?Q?Silvio_Mariji=C4=87?=) --001a114a9622b5584c053be789d0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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'll 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 aim > 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 mad= e > 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, what > 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 fu= nctionality. > > 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 see= 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 th= is > >> 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 all= ow > >> 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, actual= ly > >> 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 u= s: > >> 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 do > >> 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 meth= od > >> is (as always) up to the developers. > >> > >> (Cloning is disabled and results in an error as is because it makes no > >> 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 a= re > >> always the same, no matter what. This would also mean that no develope= r > >> 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 > > --=20 Silvio Mariji=C4=87 Software Engineer 2e Systems --001a114a9622b5584c053be789d0--