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.il...@gmail.com>
napisał(a):

> Hi Rob
>
>
> On Sun, Nov 17, 2024 at 12:15 AM 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. +=) 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 = &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=p51_x3wkfeeeGfq-&t=3319


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’s syntax Ilia’s focus on performance through
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 = new Line(start: new Point(0, 0), end: new Point(1, 1))
$line2 = $line1->with(end: new Point(2, 2))

Could CoW be integrated into Records for performance-critical cases without
sacrificing simplicity?

On Rob’s Records proposal the Syntax Simplicity and Automatic Equality make
equality straightforward and intuitive

$user1 = new User("Alice", 30)
$user2 = new User("Alice", 30)
var_dump($user1 === $user2) // true

On Ilia’s Structs proposal Copy-on-Write Semantics offers performance
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’s Records proposal is exceptionally well-suited for lightweight
immutable types and aligns with PHP’s evolution toward simplicity and
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’t
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ł Marcin Brzuchalski

Reply via email to