Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120127 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 212 invoked from network); 25 Apr 2023 16:24:14 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Apr 2023 16:24:14 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 916D01804AA for ; Tue, 25 Apr 2023 09:24:13 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 25 Apr 2023 09:24:13 -0700 (PDT) Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-3f193ca059bso31287315e9.3 for ; Tue, 25 Apr 2023 09:24:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682439852; x=1685031852; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=X+0n01/yeuS3q8RtzdBVdKGWaaDZgo31dxulrHBuKjk=; b=UxbB7ReA+tCnB1WGsx5dZmAwRAOUbhKv5kuOWw5Oh8FHpP0TjCdPturwu1QpY6KJvi v/6detMxCVTolRpzePMtEVuy05W7uARl9LgRfSP7Rx5s0sHtqLd8TezfIuNS1dyjatok qRDDzv9JKg0BI9xXtdKkPAFkcy9oWSRgJNumlpBPIqZHehJr17OKHBzfnJuTV550C1Bn EUva1Uh2lGbKNWeRY6gdWmubOsJpXgdoFeJhhr64C2CIlY1FY6kLuaWmSxj6x9qU7Dnt zpp4DVifYyZQyXeeHHRhMi+8Ug7xHF0AVxwmuW9ssLlcI2RPgo3KikAAwWJpIyThKzOj 8EVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682439852; x=1685031852; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=X+0n01/yeuS3q8RtzdBVdKGWaaDZgo31dxulrHBuKjk=; b=GWD0b8NOKVGx4mu4uMSiRf0vvoxwDX1+pZ0UCzIDnAGkzRAIQnwy0AZ8quHOIjzSZH eLC+TrlW7/JBQj29XU+V/58tq5zuhEtwH/z4ozkCcUHC8NOn27DQ4/ausPtqyk71G8rq oAM3mxVWxywlWajYuUXcAEyVujOZZOiPrNnuJyIZRu2IoxNobYoZZBYlifL0U3Phbw+F ocQSLYKScM07jiQFDQL466pWUo/2hVy8t0lKZiNzWMIMiB6cIDC5jESmnyKy34t11O1P QZOjMCpvudYycWJZsnSzyYX22zoqJmoUCvhJS/INQT61pCUbbdmEdN46D7CZVAsGMSIr f5ow== X-Gm-Message-State: AAQBX9dvGTKGHeLQs1n7E3l/OBwN86RGNba2pdshu8we4FqVHmsU7ehR DfIRMEMOFJwwq4M5GFeSPZewG9NZzN/0HUPo94o= X-Google-Smtp-Source: AKy350ZawSgEO4OX8aPFesQ1w5c4kP6c0dWoZ0nWEaa1tl7PwvLmHAG9Z7dQ78DiwxmECBJKtwb7y3JlxAHD7ktjt/Q= X-Received: by 2002:a5d:44c6:0:b0:2f2:1379:6b18 with SMTP id z6-20020a5d44c6000000b002f213796b18mr12617982wrr.9.1682439851517; Tue, 25 Apr 2023 09:24:11 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 25 Apr 2023 18:23:59 +0200 Message-ID: To: =?UTF-8?B?TcOhdMOpIEtvY3Npcw==?= Cc: PHP Internals List Content-Type: multipart/alternative; boundary="000000000000b4ac7d05fa2b8dd8" Subject: Re: [PHP-DEV] [RFC] [Discussion] Clone with From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --000000000000b4ac7d05fa2b8dd8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi again, Quite some time after mentioning the "clone with" construct the first time > (at the end of the > https://wiki.php.net/rfc/write_once_properties#run-time_behaviour > section), > finally I managed to create a working implementation for this feature whi= ch > would make it possible to properly modify readonly properties > while simplifying how we write "wither" methods: > https://wiki.php.net/rfc/clone_with > As mentioned in another thread, I'd like to make an alternative proposal for the syntax. Alex talked about it already but I think it deserves more attention. What about using a real closure to define the scope we need for cloning? That closure would take the cloned instance as argument to allow manipulating it at will. Internally, the engine would "just" call that closure just after calling __clone() if it's defined. This could look like this: $c =3D clone $a with $closure; or maybe we could skip introducing a new keyword and go for something that looks like a function call: $c =3D clone($a, $closure); I've adapted your examples from the RFC using the latter and here is how they could look like: The =E2=80=9Cwither=E2=80=9D method copy-pasted from Diactoros: class Response implements ResponseInterface { public readonly int $statusCode; public readonly string $reasonPhrase; // ... public function withStatus($code, $reasonPhrase =3D ''): Response { return clone($this, fn ($clone) =3D> [ $clone->statusCode =3D $code, $clone->reasonPhrase =3D $reasonPhrase, ]); } // ... } The property name expressions: class Foo { private $a; private $b; private $c; /** * @param array $properties */ public function withProperties(array $properties) { return clone($this, function ($clone) use ($properties) { foreach ($properties as $name =3D> $value) { $clone->$name =3D $value; } }); } } Linking the cloned instance to the original one: class LinkedObject { public function __construct( private readonly LinkedObject $next, private readonly int $number ) { $this->number =3D 1; } public function next(): LinkedObject { return clone($this, fn ($clone) =3D> [ $clone->number =3D $clone->number + 1, $this->next =3D $clone, ]); } } All these look pretty neat to me, and they come with no new syntax but a simple call-like clone() statement. Scope semantics remain the same as usual, so we already know how to interpret that aspect. Does that make sense to you? Nicolas --000000000000b4ac7d05fa2b8dd8--