Re: [RFC] Data Classes
| From: | Thomas Bley | Date: | Sat, 23 Nov 2024 17:35:41 +0000 |
| Subject: | Re: [RFC] Data Classes | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-126037@lists.php.net to get a copy of this message | ||
> Rob Landers <rob@bottled.codes> hat am 23.11.2024 14:11 CET geschrieben:
>
>
> Hello internals,
>
> Born from the Records RFC (https://wiki.php.net/rfc/records) discussion, I would like to
> introduce to you a competing RFC: Data Classes (https://wiki.php.net/rfc/dataclass).
>
> This adds a new class modifier: data. This modifier drastically changes how classes work,
> making them comparable by value instead of reference, and any mutations behave more like arrays than
> objects (by vale). If desired, it can be combined with other modifiers, such as readonly, to enforce
> immutability.
>
> I've been playing with this feature for a few days now, and it is surprisingly intuitive
> to use. There is a (mostly) working implementation available on GitHub
> (https://github.com/php/php-src/pull/16904) if you want to have a go at it.
>
> Example:
>
> data class UserId { public function __construct(public int $id) {} }
>
> $user = new UserId(12);
> // later
> $admin = new UserId(12);
> if ($admin === $user) { // do something } // true
>
> Data classes are true value objects, with full copy-on-write optimizations:
>
> data class Point {
> public function __construct(public int $x, public int $y) {}
> public function add(Point $other): Point {
> // illustrating value semantics, no copy yet
> $previous = $this;
> // a copy happens on the next line
> $this->x = $this->x + $other->x;
> $this->y = $this->y + $other->y;
> assert($this !== $previous); // passes
> return $this;
> }
> }
>
> I think this would be an amazing addition to PHP.
>
> Sincerely,
>
> — Rob
>
Thanks for the rfc!
From userland perspective I would prefer to have the cloning more explicitly, e.g.
return clone $this($this->x + $other->x, $this->y + $other->y);
or
return clone $this(x: $this->x + $other->x); // clone with y unchanged
Best Regards
Thomas