Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125985 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 4F16D1A00BD for <internals@lists.php.net>; Tue, 19 Nov 2024 11:26:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1732015769; bh=XziSn8Y28IUsMnvu3vt3wXSt/xQM3yg+HyDP1o05E3M=; h=References:In-Reply-To:From:Date:Subject:To:From; b=bEwLaYXsqw895pyEiJJ5sHtHtPPEPgWAJUVvPxInYggidi89z95asXMzqSJV6dn9M WbgxagnJuqRnIACNCxZCZU8fTZuh+eIyjEV53P7lrTh7lzJTVgySmQJDelAC6iguoe xTJZ9XnMG74gK4VPYTxW/aqAcvbpnjB8ivPnwj3cHBvKxHKDSZ6e3iy+JkySUQxfWK 05ep/JLTPu2ffGivQnK8jmvtbLZLLjjyKBS7Um316AlMGyt3fdXIk1fqbcCrDiVQvw RMVrt4UF0W+W7j2pmFQsS2uQdYTLB1qT0BsohZKSxaqQMxlWbcUX+Mkgz3qDC4IEcc mhLNlml/APQDg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 98EE2180037 for <internals@lists.php.net>; Tue, 19 Nov 2024 11:29:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: <michal.brzuchalski@gmail.com> Received: from mail-yb1-f174.google.com (mail-yb1-f174.google.com [209.85.219.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for <internals@lists.php.net>; Tue, 19 Nov 2024 11:29:27 +0000 (UTC) Received: by mail-yb1-f174.google.com with SMTP id 3f1490d57ef6-e38939a89bfso1983061276.3 for <internals@lists.php.net>; Tue, 19 Nov 2024 03:26:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732015608; x=1732620408; darn=lists.php.net; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=vf3njAMnzw1Zu8FbtZHSm2enIQAp8jvhfcIJV9LUSsk=; b=OkmNrrl1g70mZ9XN+zGLX+t8uLe94LT2hUOig+lNsy05qGxq9ojme2ax/DCvH99z8f h+3KZsU3IDMKOfffAGo26Mkvl/V1MpBLbA/CX7OFL9KHOo1w96O81kT9YkDQddC6Aj9E zwju6Ey3zUE5CURwfm2ylGwgNJr9cO13TG9siInpbLRqrBdotZinwhqhKENwJDvAromh DHnoXeXHnAZJ08d3PnRO9wogsicETI6ddxb+0LHr+7DWWBpuKnXKjSx9sK44fUQn2BwF 81ZH1kFb6U5/s0CFNApVc5EHNTbs7AQCutPrmC9l7z+74keq9PGouUATGD7nyG9ezx05 PqSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732015608; x=1732620408; h=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=vf3njAMnzw1Zu8FbtZHSm2enIQAp8jvhfcIJV9LUSsk=; b=OS1rlEOQBbJRxig4NDCYZeyfuQXM70oduuya1/4/xpkXLuNgbGVcoPX4p8oTYYv2Q5 qFBwv/4st5X9ZwvH48dmllEINkq3JnkSJo5Ud2pEAmYuMN9d6dzPa3EThVdkshINq/LI OBt3yBwm8Z9xdtvOeBOFEFciScmSkkJ1906Ne1mQnou/fUT77CjWHY2xUjl1bhN+mehL 7WOgFSiD1U6hAANnNUU5bx21U4t6JKPyfX6xpaE439z9HN2U4GZKvx7TxuCEJ2KLMhre cdCz2AIM78e7l9/mxL4Q7vxiV+GvigSSxmiKWCrqj99ihO5rzbWr4IFx314Gz8CbXtOa 5lkA== X-Gm-Message-State: AOJu0YwIfoY/Yx3JOQOCBd77KHVKoH8YWXgH648w1LM9G3DmMBMC729r qS0VHXSNQgulYVrNWewykhw66qbLzVwvIg4xMDGVG8flgrpMr6p6+WjHEY4dnfz2SGEpxXMWMGh ygcZ8toIR7qUto4rX5HTRYpCANQ5FFdDA X-Google-Smtp-Source: AGHT+IG8z3qfcYMJv2s4ucx5Q0XOYafol8qZkHgKEZx8n1jnOnRk9AZiu7Sym0eJe8mUmx8gu/4xDlXvU0Z7jEm4RsY= X-Received: by 2002:a05:6902:1105:b0:e2e:35db:9b94 with SMTP id 3f1490d57ef6-e38263bbc04mr13464519276.39.1732015608119; Tue, 19 Nov 2024 03:26:48 -0800 (PST) Precedence: bulk list-help: <mailto:internals+help@lists.php.net list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net> list-post: <mailto:internals@lists.php.net> List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <d603f372-5f58-4308-aba1-151c35f3aa94@app.fastmail.com> <CAPyj-LCtzF6FKwGakaouyueaLRQsu=B4uASFZKEG4x+-a2J2iA@mail.gmail.com> In-Reply-To: <CAPyj-LCtzF6FKwGakaouyueaLRQsu=B4uASFZKEG4x+-a2J2iA@mail.gmail.com> Date: Tue, 19 Nov 2024 12:26:37 +0100 Message-ID: <CABdc3WrOn3s3qSt_aXHVk1qP6S5HdEvxgbem1oRuBVBe-6V_iA@mail.gmail.com> Subject: Re: [PHP-DEV] RFC: Records To: PHP internals <internals@lists.php.net> Content-Type: multipart/alternative; boundary="0000000000001148860627424f20" From: michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Marcin_Brzuchalski?=) --0000000000001148860627424f20 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Rob and Ilia Thank you both for your detailed proposals and the efforts you put into shaping this important feature for PHP It is clear a lot of thought has gone into both approaches and I appreciate the opportunity to share my thoughts. niedz., 17 lis 2024 o 01:17 Ilija Tovilo <tovilo.ilija@gmail.com> napisa=C5=82(a): > Hi Rob > > > On Sun, Nov 17, 2024 at 12:15=E2=80=AFAM Rob Landers <rob@bottled.codes> = wrote: > > > > Hello internals, > > > > I'm ready as I'm going to be to introduce to you: "Records" > https://wiki.php.net/rfc/records! > > Thanks for your proposal. I very much agree that value semantics are a > highly desirable feature. I sent out my concept proposal on how this > may be achieved through structs some months ago. [1] There are some > remaining technical challenges, but the PoC looks promising. [2] > > I personally do not think immutable data structures are a good > solution to the problem, and I don't feel like we need another, > slightly shorter way to do the same thing. In my proposal, I mentioned > that there are two primary issues with immutable data structures: > > 1. They are expensive. Any modification of the class requires a clone > of the object by design, even when the cloned object is immediately > discarded. This is most noticeable for lists and other growable data > types, because they are large and change frequently. An O(n) insertion > becomes infeasible very fast. > 2. The clone is explicit, which gets old pretty quickly. Many of PHPs > quality-of-life features like op-assign (e.g. +=3D) become unusable. > > Structs would instead be fully-fledged objects that adopt CoW > (copy-on-write) semantics, which is how PHP already implements arrays. > Essentially, objects are automatically cloned when they are changed > _and_ when the object is referenced from multiple places. If the > object is not referenced anywhere else, it may be safely mutated > without a clone, as there is nobody to observe this side-effect. When > a shared object is mutated multiple times (e.g. an append to a list in > a loop), only the first mutation requires a clone. It's also something > you don't need to think about, it just happens. > > As mentioned, the main motivation of my proposal is to implement new > dedicated data structures like Vectors, Maps, Sets, etc. in PHP > (userland and extensions) without sacrificing ergonomics or > performance. However, they would also solve the same challenges for > simple data objects. IMO, immutability was never a great solution to > the problem of "spooky action at a distance". Mutability itself is not > a problem, just shared mutability. > > Note that this concept is heavily inspired by Swift, Rust and likely > other languages I don't know. Chris Lattner (the original author of > LLVM and Swift) has shared very similar thoughts in an interview > recently. [3] > > If the primary motivation of your RFC is to reduce boilerplate, then > it's true that structs would not help much. I do wonder whether 1. we > need even shorter code and 2. if we do, whether it's something that > could be added to classes alike, rather than tying it to records when > it could be more generic instead. > > A small note: The $test =3D &Test(); syntax is ambiguous, as it's > already legal. https://3v4l.org/CE5rt > > Ilija > > [1] https://externals.io/message/122845 > [2] https://github.com/php/php-src/pull/13800 > [3] https://youtu.be/JRcXUuQYR90?si=3Dp51_x3wkfeeeGfq-&t=3D3319 The goal of Records as I see it is to provide a concise syntax for defining immutable value objects optimized for simplicity and common use cases and I strongly align with this goal. The concise syntax in your proposal is a significant advantage for small immutable types record User(string $name, int $age) This simplicity eliminates boilerplate making it an excellent fit for common scenarios like DTOs or configuration objects Structs are designed to provide immutability with Copy-on-Write semantics ensuring efficiency when dealing with large or nested structures While I prefer Rob=E2=80=99s syntax Ilia=E2=80=99s focus on performance thr= ough Copy-on-Write is compelling. For example CoW optimization could make scenarios like this more efficient struct Line { public Point $start public Point $end } $line1 =3D new Line(start: new Point(0, 0), end: new Point(1, 1)) $line2 =3D $line1->with(end: new Point(2, 2)) Could CoW be integrated into Records for performance-critical cases without sacrificing simplicity? On Rob=E2=80=99s Records proposal the Syntax Simplicity and Automatic Equal= ity make equality straightforward and intuitive $user1 =3D new User("Alice", 30) $user2 =3D new User("Alice", 30) var_dump($user1 =3D=3D=3D $user2) // true On Ilia=E2=80=99s Structs proposal Copy-on-Write Semantics offers performan= ce advantages for large or nested structures making it a great fit for optimizing immutability but the Explicit Equality - while useful for complex cases explicit equality checks introduce additional boilerplate for simple scenarios. Rob=E2=80=99s Records proposal is exceptionally well-suited for lightweight immutable types and aligns with PHP=E2=80=99s evolution toward simplicity a= nd developer experience. That said, Ilia's CoW optimizations are valuable for performance and could complement Records in specific cases. Thank you both again for your hard work and thoughtful proposals. To move this discussion forward perhaps we could organize a community vote to gauge which capabilities are preferred overall. This could help the team better understand the direction the community supports and explore possible hybrid solutions if needed. On a related note I was recently asked about my old draft RFC proposal for Structs[1] and whether it was abandoned or forgotten. While it didn=E2=80= =99t address many of the ideas you have both raised, it was built with composition in mind from the start. I hope that such capabilities could also be explored in future extensions as they would bring additional flexibility to these immutable types. [1] https://wiki.php.net/rfc/structs#fields_composition Best regards -- Micha=C5=82 Marcin Brzuchalski --0000000000001148860627424f20 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr">Hi Rob and Ilia<br><br>Thank you both for= your detailed proposals and the efforts you put into shaping this importan= t feature for PHP It is clear a lot of thought has gone into both approache= s and I appreciate the opportunity to share my thoughts.<br></div><br><div = class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">niedz., 17 lis = 2024 o 01:17=C2=A0Ilija Tovilo <<a href=3D"mailto:tovilo.ilija@gmail.com= ">tovilo.ilija@gmail.com</a>> napisa=C5=82(a):<br></div><blockquote clas= s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r= gb(204,204,204);padding-left:1ex">Hi Rob<br> <br> <br> On Sun, Nov 17, 2024 at 12:15=E2=80=AFAM Rob Landers <rob@bottled.codes&= gt; wrote:<br> ><br> > Hello internals,<br> ><br> > I'm ready as I'm going to be to introduce to you: "Record= s" <a href=3D"https://wiki.php.net/rfc/records" rel=3D"noreferrer" tar= get=3D"_blank">https://wiki.php.net/rfc/records</a>!<br> <br> Thanks for your proposal. I very much agree that value semantics are a<br> highly desirable feature. I sent out my concept proposal on how this<br> may be achieved through structs some months ago. [1] There are some<br> remaining technical challenges, but the PoC looks promising. [2]<br> <br> I personally do not think immutable data structures are a good<br> solution to the problem, and I don't feel like we need another,<br> slightly shorter way to do the same thing. In my proposal, I mentioned<br> that there are two primary issues with immutable data structures:<br> <br> 1. They are expensive. Any modification of the class requires a clone<br> of the object by design, even when the cloned object is immediately<br> discarded. This is most noticeable for lists and other growable data<br> types, because they are large and change frequently. An O(n) insertion<br> becomes infeasible very fast.<br> 2. The clone is explicit, which gets old pretty quickly. Many of PHPs<br> quality-of-life features like op-assign (e.g. +=3D) become unusable.<br> <br> Structs would instead be fully-fledged objects that adopt CoW<br> (copy-on-write) semantics, which is how PHP already implements arrays.<br> Essentially, objects are automatically cloned when they are changed<br> _and_ when the object is referenced from multiple places. If the<br> object is not referenced anywhere else, it may be safely mutated<br> without a clone, as there is nobody to observe this side-effect. When<br> a shared object is mutated multiple times (e.g. an append to a list in<br> a loop), only the first mutation requires a clone. It's also something<= br> you don't need to think about, it just happens.<br> <br> As mentioned, the main motivation of my proposal is to implement new<br> dedicated data structures like Vectors, Maps, Sets, etc. in PHP<br> (userland and extensions) without sacrificing ergonomics or<br> performance. However, they would also solve the same challenges for<br> simple data objects. IMO, immutability was never a great solution to<br> the problem of "spooky action at a distance". Mutability itself i= s not<br> a problem, just shared mutability.<br> <br> Note that this concept is heavily inspired by Swift, Rust and likely<br> other languages I don't know. Chris Lattner (the original author of<br> LLVM and Swift) has shared very similar thoughts in an interview<br> recently. [3]<br> <br> If the primary motivation of your RFC is to reduce boilerplate, then<br> it's true that structs would not help much. I do wonder whether 1. we<b= r> need even shorter code and 2. if we do, whether it's something that<br> could be added to classes alike, rather than tying it to records when<br> it could be more generic instead.<br> <br> A small note: The $test =3D &Test(); syntax is ambiguous, as it's<b= r> already legal. <a href=3D"https://3v4l.org/CE5rt" rel=3D"noreferrer" target= =3D"_blank">https://3v4l.org/CE5rt</a><br> <br> Ilija<br> <br> [1] <a href=3D"https://externals.io/message/122845" rel=3D"noreferrer" targ= et=3D"_blank">https://externals.io/message/122845</a><br> [2] <a href=3D"https://github.com/php/php-src/pull/13800" rel=3D"noreferrer= " target=3D"_blank">https://github.com/php/php-src/pull/13800</a><br> [3] <a href=3D"https://youtu.be/JRcXUuQYR90?si=3Dp51_x3wkfeeeGfq-&t=3D3= 319" rel=3D"noreferrer" target=3D"_blank">https://youtu.be/JRcXUuQYR90?si= =3Dp51_x3wkfeeeGfq-&t=3D3319</a></blockquote><div><br></div>The goal of= Records as I see it is to provide a concise syntax for defining immutable = value objects optimized for simplicity and common use cases<br>and I strong= ly align with this goal. The concise syntax in your proposal is a significa= nt advantage for small immutable types<br><br></div><div class=3D"gmail_quo= te">record User(string $name, int $age)<br><br></div><div class=3D"gmail_qu= ote">This simplicity eliminates boilerplate making it an excellent fit for = common scenarios like DTOs or configuration objects<br><br>Structs are desi= gned to provide immutability with Copy-on-Write semantics ensuring efficien= cy when dealing with large or nested structures<br><br>While I prefer Rob= =E2=80=99s syntax Ilia=E2=80=99s focus on performance through Copy-on-Write= is compelling. For example CoW optimization could make scenarios like this= more efficient</div><div class=3D"gmail_quote"><br>struct Line {<br>=C2=A0= =C2=A0 public Point $start<br>=C2=A0 =C2=A0 public Point $end<br>}<br><br>= $line1 =3D new Line(start: new Point(0, 0), end: new Point(1, 1))<br>$line2= =3D $line1->with(end: new Point(2, 2))<br><br></div><div class=3D"gmail= _quote">Could CoW be integrated into Records for performance-critical cases= without sacrificing simplicity?<br><br>On Rob=E2=80=99s Records proposal t= he Syntax Simplicity and Automatic Equality=C2=A0make equality straightforw= ard and intuitive<br><br></div><div class=3D"gmail_quote">$user1 =3D new Us= er("Alice", 30)<br>$user2 =3D new User("Alice", 30)<br>= var_dump($user1 =3D=3D=3D $user2) // true<br><br>On Ilia=E2=80=99s Structs = proposal=C2=A0Copy-on-Write Semantics offers performance advantages for lar= ge or nested structures making it a great fit for optimizing immutability b= ut the=C2=A0Explicit Equality - while useful for complex cases explicit equ= ality checks introduce additional boilerplate for simple scenarios.<br><br>= Rob=E2=80=99s Records proposal is exceptionally well-suited for lightweight= immutable types and aligns with PHP=E2=80=99s evolution toward simplicity = and developer experience. That said, Ilia's CoW optimizations are valua= ble for performance and could complement Records in specific cases.<br><br>= Thank you both again for your hard work and thoughtful proposals. To move t= his discussion forward perhaps we could organize a community vote to gauge = which capabilities are preferred overall. This could help the team better u= nderstand the direction the community supports and explore possible hybrid = solutions if needed.<br><br>On a related note I was recently asked about my= old draft RFC proposal for Structs[1] and whether it was abandoned or forg= otten. While it didn=E2=80=99t address many of the ideas you have both rais= ed, it was built with composition in mind from the start. I hope that such = capabilities could also be explored in future extensions as they would brin= g additional flexibility to these immutable types.<br><br>[1]=C2=A0<a href= =3D"https://wiki.php.net/rfc/structs#fields_composition">https://wiki.php.n= et/rfc/structs#fields_composition</a></div><div class=3D"gmail_quote"><br>B= est regards</div><div class=3D"gmail_quote">--<br>Micha=C5=82 Marcin Brzuch= alski</div></div> --0000000000001148860627424f20--