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 &lt;<a href=3D"mailto:tovilo.ilija@gmail.com=
">tovilo.ilija@gmail.com</a>&gt; 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 &lt;rob@bottled.codes&=
gt; wrote:<br>
&gt;<br>
&gt; Hello internals,<br>
&gt;<br>
&gt; I&#39;m ready as I&#39;m going to be to introduce to you: &quot;Record=
s&quot; <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&#39;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&#39;s also something<=
br>
you don&#39;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 &quot;spooky action at a distance&quot;. 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&#39;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&#39;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&#39;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 &amp;Test(); syntax is ambiguous, as it&#39;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-&amp;t=3D3=
319" rel=3D"noreferrer" target=3D"_blank">https://youtu.be/JRcXUuQYR90?si=
=3Dp51_x3wkfeeeGfq-&amp;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-&gt;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(&quot;Alice&quot;, 30)<br>$user2 =3D new User(&quot;Alice&quot;, 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&#39;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--