Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:95732 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 1898 invoked from network); 7 Sep 2016 10:29:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Sep 2016 10:29:09 -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.54 as permitted sender) X-PHP-List-Original-Sender: marijic.silvio@gmail.com X-Host-Fingerprint: 209.85.214.54 mail-it0-f54.google.com Received: from [209.85.214.54] ([209.85.214.54:36335] helo=mail-it0-f54.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 4F/CC-18051-0FBEFC75 for ; Wed, 07 Sep 2016 06:29:07 -0400 Received: by mail-it0-f54.google.com with SMTP id i184so189044222itf.1 for ; Wed, 07 Sep 2016 03:29:04 -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=F+JT/p9attKKeup0gGaP6Q/yOCxA89z2moL6r4mf9uo=; b=PId4rL2sqAwB7PIHIIafMQsK3js8vU6ynzi1JeYzzUTbjeLWnYRKKsRWlpuspqNuEX K0jH0Te3M3pTrTSkpLrLQiboJZQmo29yuvTODg4p7cUe7PbJ2nlOmxZPzXdX/HsQZJbZ +RQI/wUiC5l6VLRVz3lFYXHorx6rKUIGGQRGHsWwnMrta7astGlPGvcraYWgGbuMTzVz fxRgO+9sOZBmNmOdvTJpInJ4E5FPB33lQ1e308nNgCvuzcyrKFvnpbZQympzkN5NM7yD OM4PZH84UDIyj0eEx+NTXCSedZUq3MzzrkY8uKgmwNgGdcJKGukNizeC+TAeNGw9leXl kU7g== 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=F+JT/p9attKKeup0gGaP6Q/yOCxA89z2moL6r4mf9uo=; b=h1b0+fR8w7QnD8C8CToa4iLXTNzsjKmTD1xuh3qFOH49PNQ3WIYJSm0GVHKVSeoeT/ scMzcKIHE3uraDD9KMJC9WJzTwvZ2hO1op5SAYR0i/aPqEoC5O8DP6j01mS7NmidX+Dh qzK7LC708DVEgiZvCUEvsuQ4WFBZmBSvaPxk+wwqpeOKNsgrGS5eUFQnPojuI/naAQMO 37rhN5fpCfFWITlPwaB0qpOU/cTIfhS3rp9UB2bZfUUYcieq/r/8+9XftskFanPJHda7 hs72JLYoe8k2+4VPXhwab3ukIo/2Ab99PF+/hcYja7PxkhSKeA2IhY+4ObWaGIhGCN8k XX7Q== X-Gm-Message-State: AE9vXwNv5EyL5rLCEtntGPDBGjST/NaVO8Ka6U9ae+H55cIKLAQyAG9kcJ758f83Eqj7NMtMUJ0BXHuu3Y4VfA== X-Received: by 10.36.152.5 with SMTP id n5mr4949579itd.79.1473244142103; Wed, 07 Sep 2016 03:29:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.237.74 with HTTP; Wed, 7 Sep 2016 03:29:01 -0700 (PDT) Received: by 10.36.237.74 with HTTP; Wed, 7 Sep 2016 03:29:01 -0700 (PDT) In-Reply-To: <3bbd1cd2-23a0-25da-1fca-4df133672b98@rochette.cc> 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> <3bbd1cd2-23a0-25da-1fca-4df133672b98@rochette.cc> Date: Wed, 7 Sep 2016 12:29:01 +0200 Message-ID: To: Mathieu Rochette Cc: PHP Internals List Content-Type: multipart/alternative; boundary=94eb2c05f7f8c203f3053be8617f Subject: Re: [PHP-DEV] RFC - Immutable classes From: marijic.silvio@gmail.com (=?UTF-8?Q?Silvio_Mariji=C4=87?=) --94eb2c05f7f8c203f3053be8617f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable @Mathieu, Object can not be modified neither internally or externally, question is if you clone object where should we allow modification of cloned object On Sep 7, 2016 12:13 PM, "Mathieu Rochette" wrote: > > > On 07/09/2016 11:05, Stephen Reay wrote: > >> (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 possi= ble. >> >> >> If the goal of an immutable class is to allow public properties to be >> made read-only, my expectation would be that: >> > I don't think this is the goal, in immutable classes, the object itself > should not be able to alter itself either (whatever the visibility of the > property is) > >> >> - 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 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 i= s >>>> 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 > > --94eb2c05f7f8c203f3053be8617f--