On Mon, Jun 28, 2021, at 1:36 PM, Nicolas Grekas wrote: > >> > Actually, we talked off the list about a way to possibly make this work > >> > with __clone(): > >> > > >> > We could allow __clone to have one argument, the object being cloned. > >> And > >> > when the signature declares this argument, then all readonly properties > >> > would be set as uninitialized on $this. > >> > > >> > A typical __clone function would look like this with readonly > >> properties: > >> > function __clone(object $original) > >> > { > >> > $this->readonlyProp = clone $original->readonlyProp; > >> > } > >> > > >> > That would turn my vote into a +1 if that could be made to work! > >> > >> That sounds like it would support deep cloning, but not with-er methods. > >> There's no way to provide a changed value. It also would mean a lot of > >> work on larger objects to transfer across all the properties. I don't > >> really see what this would add. > >> > > > > Can you elaborate about the lack of support for withers? Having some work > > to do doesn't look like an issue to me, especially when there is no > > alternative to compare that too. > > > > I sent that too fast, I agree about withers... :) > I'm looking for a way to +1 that RFC... > Any other idea?
IMO, the best solution to `readonly` and with-er methods is the discussed-but-not-proposed clone-with syntax. This RFC on its own: class Point { public function __construct( public readonly int $x, public readonly int $y, public readonly int $z, } public function withX(int $new): static { return new static( x: $new, y: $this->y, z: $this->z, ); } // And the same for withY() and withZ() } That does work, it's just ugly, and the amount of work needed scales exponentially with the number of properties. Same thing but adding clone-with: class Point { public function __construct( public readonly int $x, public readonly int $y, public readonly int $z, } public function withX(int $new): static { return clone($this) with {x: $new}; } // And the same for withY() and withZ() } The extra work needed here scales linearly with the number of properties. Clone-with isn't even a full proposal yet so definitely won't make it into 8.1. But, it's a standalone feature that could be added on its own later and complement `readonly`. (In case anyone hadn't noticed, I am a big fan of "features for free", which you get by designing smaller features to complement each other and become more than the sum of their parts.) The alternative is asymmetric visibility, which would allow for a withX() method like this: public function withX(int $new) { $that = clone($this); $that->x = $new; return $that; } Which is basically what withX() methods all do now already, so no change from status quo. It's more code per-property than clone-with, but still scales linearly. Nikita has made it clear he wants to proceed with readonly for now, though, and consider whether to also add asymmetric visibility in the Future(tm). I don't really see an alternative "easy fix" for readonly and with-er methods. I'll probably be voting +1 on readonly myself as is, even if it does make with-ers harder, because it would at least make the case that either clone-with or asymmetric visibility (or both, ideally) will be a necessity in 8.2. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php