Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112699 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 88701 invoked from network); 31 Dec 2020 14:29:29 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 31 Dec 2020 14:29:29 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BE9221804C4 for ; Thu, 31 Dec 2020 06:04:25 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_20,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 31 Dec 2020 06:04:25 -0800 (PST) Received: by mail-lf1-f51.google.com with SMTP id o17so44235875lfg.4 for ; Thu, 31 Dec 2020 06:04:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=LNKb2QKG2WSSzpKMKk7Vx2+1mctC4kr3gMV+cB1mqlc=; b=Dhw0truxciaJlfEq2+BDP+oGAmmk3YZfDPlzD8Mv/EArKI+/g5uSAPy9zhYmPc5qJa DgjJucMbNog/oRZWK9XzxTIfdQmAja4Pb639KC+oBUOfTPeYHpP+Ub802lMZZSD/VWWs BXePuF+6vXsI3ngquW+5QbHsaCuXWzrj62Zvri3RorhHxviEs51v3U8MPQX4Ype2Zcad U6F1YMG+kOAakwZWCzV1RatOWRyIA38kSaDcOo+9gPf1RY1F958pyvFNS6UO9NWbQt3q kETBDJs0mysqpCauwTXEo0qbkUZ2vgq1rgeQr0upicckvEl3KWS4oghCAvWKyYlCn2ry QgSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=LNKb2QKG2WSSzpKMKk7Vx2+1mctC4kr3gMV+cB1mqlc=; b=NR7/q+vfBQAMCD9A+epHgqMqd9GghiSPta90WRugUTgp9xofzzQWynVKIVHnI8ZVHh ScvhibJ8W1BpcXF30fF401CCKT0Dm9vPrY3UupSS1dVYocwaH+2bmSBuGww44WeYn2Ql 2jtEXAfgwG5hU7lhTw8ScwBEKiKOdcD7smsvnfefDc5qT7M0ZUYr4CZy0g8+jFxgSex7 G4voxMrd2oiu16FS+bglSdJ73nTNK5bUSG0u1RecZ34jK+yR1UlT+/AM7w6EdfBLk3GP rb5kAjJ86TfH6Sf30+HwM+38eYBuRvGTf4ghtFQZkeMgbMmE3Sjk7m3rACB/YOZHjnq2 +EGA== X-Gm-Message-State: AOAM533DC3nO62L6Igo4qyXrh/NnH3bCF0tGHbTvBjaTYlji18gVo7r7 EfJEOQup9onUAerbTlRLtyS41v5PxpRIlLWNwG0= X-Google-Smtp-Source: ABdhPJwFE910zOcb4TEYaUHCpuFl9uuDMIF215EYsBBXaI20YVYhBPmlwEJ+3npjGoarrbTGHo8wm3kUxMOY4NZ3UPk= X-Received: by 2002:ac2:5970:: with SMTP id h16mr27776406lfp.338.1609423458986; Thu, 31 Dec 2020 06:04:18 -0800 (PST) MIME-Version: 1.0 Received: by 2002:ab3:7110:0:0:0:0:0 with HTTP; Thu, 31 Dec 2020 06:04:18 -0800 (PST) In-Reply-To: <30906866-1971-8395-05a0-fd78d054bb89@gmail.com> References: <1d0abb04-4987-43a9-85bc-bccc3bd6be9a@www.fastmail.com> <03108284-740a-4a5d-130f-15b2e67e9df9@mabe.berlin> <459d7ff7-e553-dce9-7d43-c3b1e772e572@gmail.com> <7f4fe9ca-1c20-6f69-cef0-a9718af742a3@gmail.com> <30906866-1971-8395-05a0-fd78d054bb89@gmail.com> Date: Thu, 31 Dec 2020 14:04:18 +0000 Message-ID: To: Rowan Tommins Cc: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Analysis of property visibility, immutability, and cloning proposals From: olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=) 2020-12-31 12:37 GMT, Rowan Tommins : > Hi Mike and Olle, > > > On 31/12/2020 00:24, Mike Schinkel wrote: >> A different perspective is that "withX" methods require a mental >> translation where "addX" methods do not, much like how a person whose >> native language is English will find it a challenge to (or cannot) "thin= k" >> in French. > > > I wonder if that's just about the choice of names, rather than the > mutability/immutability itself? > > >>> $start =3D MyDate::today(); >>> $end =3D $start->withAddedDays(5); >>> >>> vs >>> >>> $start =3D MyDate::today(); >>> $end =3D clone $start; >>> $end->addDays(5); >> Ignoring that you are comparing apples and oranges (scalars to objects,) >> the latter is easier to reason about IMO. > > > Ignoring the distinction between "scalar" and "object" was kind of the > point: they are both "values", and are more naturally treated the same > as differently. > > > To take a different example, consider writing a new number type (for > arbitrary precision, or complex numbers, or whatever), with an "add" > method. > > The mutable version looks something like this: > > public function add($other) { > $this->value =3D $this->value + $other; > } > > and has to be used like this: > > $start =3D new MyNumber(1); > $end =3D clone $start; > $end->add(5); > > > The immutable version might look more like this: > > public function add($other) { > return clone $this with { value: $this->value + $other }; > } > > and is used like this: > > $start =3D new MyNumber(1); > $end =3D $start->add(5); > > That's much closer to the "$end =3D $start + 5;" we're used to. > > > On 30/12/2020 18:42, Olle H=C3=A4rstedt wrote: >>> To put it a different way, value types naturally form*expressions*, >>> which mutable objects model clumsily. It would be very tedious if we ha= d >>> to avoid accidentally mutating the speed of light: >>> >>> $e =3D (clone $m) * ((clone $c) ** 2); >> Using a variable on right-hand side does not automatically create an >> alias, so in the above case you don't have to use clone. > > > Whether or not the type system forced you to, you'd have to use clone if > the values were implemented as mutable. Switching to methods again may > make that clearer: > > $c =3D new MyNumber(299_792_458); > $m =3D new MyNumber(10); > $e =3D $m->multiply( $c->square() ); > > If multiply() and square() are mutating state, rather than returning new > instances, $c is now 89875517873681764, which is going to totally mess > up the universe... > > > Regards, > > -- > Rowan Tommins > [IMSoP] Yes, of course you can find use-cases where immutability is a better choice, just like I can find use-cases where (constrained) mutability is better. The point is not to replace one tool with another, but rather adding another tool to the toolbox. The web dev discourse is one-sided with regard to immutability, I think. Wish I had time to implement a PR to Psalm to show something more concrete... Again, if you only have a hammer, everything looks like a nail. :) Olle