On 02/04/2024 01:17, Ilija Tovilo wrote:
I'd like to introduce an idea I've played around with for a couple of
weeks: Data classes, sometimes called structs in other languages (e.g.
Swift and C#).
Hi Ilija,
I'm really interested to see how this develops. A couple of thoughts
that immediately occurred to me...
I'm not sure if you've considered it already, but mutating methods
should probably be constrained to be void (or maybe "mutating" could
occupy the return type slot). Otherwise, someone is bound to write this:
$start = new Location('Here');
$end = $start->move!('There');
Expecting it to mean this:
$start = new Location('Here');
$end = $start;
$end->move!('There');
When it would actually mean this:
$start = new Location('Here');
$start->move!('There');
$end = $start;
I seem to remember when this was discussed before, the argument being
made that separating value objects completely means you have to spend
time deciding how they interact with every feature of the language.
Does the copy-on-write optimisation actually require the entire class to
be special, or could it be triggered by a mutating method on any object?
To allow direct modification of properties as well, we could move the
call-site marker slightly to a ->! operator:
$foo->!mutate();
$foo->!bar = 42;
The first would be the same as your current version: it would perform a
CoW reference separation / clone, then call the method, which would
require a "mutating" marker. The second would essentially be an
optimised version of $foo = clone $foo with [ 'bar' => 42 ]
During the method call or write operation, readonly properties would
allow an additional write, as is the case in __clone and the "clone
with" proposal. So a "pure" data object would simply be declared with
the existing "readonly class" syntax.
The main drawback I can see (outside of the implementation, which I
can't comment on) is that we couldn't overload the === operator to use
value semantics. In exchange, a lot of decisions would simply be made
for us: they would just be objects, with all the same behaviour around
inheritance, serialization, and so on.
Regards,
--
Rowan Tommins
[IMSoP]