Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122895 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 402A81A009C for ; Tue, 2 Apr 2024 20:10:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712088671; bh=TZ1kWbMsvVfrblSmlBUwZifz/i79RHXc2/loubDM/PI=; h=Date:Subject:To:References:From:In-Reply-To:From; b=hpc2cCqW/C4Fl9AxcB68SDfr5SjzIMcAGnkuAtMGv6YXGmkF1mW6+4/hAbAc8Gwgo Qrp6/3EmzFdEqVQG56LP0p0zaxr3Gt4T87O7cb/EC5wceERUAvV8hx1x90rwq4nnwR jFlqNlnPvHbEM4FTQs9obFvS/Jn5bO+ESIFqkm9LDHsoR6kMDLdUr51bXkd5Y/bD/9 ehGA8VMJ3qk6yWqGKaFc73qJKcaZveAilGtdeK0KUoiUrBfYyNmGGE8VQCwNm5cr+C 2ydPOlDm2jD1bdvoOzrwgLRWKKHvXO9MocyD8kVFrONnQLJDDx45VFzRBpmg7TCKKt RGcA+JGeUURNA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EEE55180004 for ; Tue, 2 Apr 2024 20:11:09 +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.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout7-smtp.messagingengine.com (fout7-smtp.messagingengine.com [103.168.172.150]) (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 ; Tue, 2 Apr 2024 20:11:09 +0000 (UTC) Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfout.nyi.internal (Postfix) with ESMTP id B0C1713801ED for ; Tue, 2 Apr 2024 16:10:40 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute7.internal (MEProxy); Tue, 02 Apr 2024 16:10:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm2; t=1712088640; x=1712175040; bh=KyowYWrvPA Yz95lOtchuoSBeBnipBCOVsXQI/f7AKMY=; b=Ue6u+HUxUNGntCTD8aZcW/R3ba JkqtbzKpaO6IRBNYoa7Z7n/0T0hrNOVDkkJR/A+rQA59Xj3GjLOay6JelPtKQP8q k0339r6snpPhbYBfMD8yhjN/QVJt/GQmCHmVUuIijN4MRr2HAwyKCOV54i6HHOAh eBHKWdAk77dUDnsWBHl0W/QwWlc5v49Yg0+aLARLQOyQN6oeMpVkEgOy/xcneevg pBygkgxUfx/fYw7UrClwPiC1U3PItv17rizHwNMcF6mHXeJbDsZfMgOyTjrgUjqa 7w7+9fN5GjCzYobVEwegjdhRq19Shce1JA/efmP7wAyxWrLwnVwlctZzBCEA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1712088640; x=1712175040; bh=KyowYWrvPAYz95lOtchuoSBeBnip BCOVsXQI/f7AKMY=; b=DvynqSA/iDTz2UQIDpiLdcW1awiz7vFfA1VIRha6YXq6 FC+d7t9RKBPmws4ZYB3noeGhg7Uf2QJJfWh/fCYK5mVzYvxUky5ce/fYVSkZwjgo i1YMBNdD+WlmUDJ3yzZIpGbw7WwpG845inCpq7GK6RCVfnPkoqpCgQmmB1+DQk00 7IYE/GBu1zz0JfZqvDhBsma7PWDKj0weK4AACDIiJSvJcA15/LlAN6iGB0HZxD5O UmyLZuyV0rxYwRvFeu67xiuRlK+HvRVdWHKe+C8hg12t9IUfWVnJBsA1MTHbl6r6 ZoUubdVGY3STifCA3a/fkpy4fHGpjvxUL3z3KGtNDQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrudefvddgudegiecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurheptgfkffggfgfuvfhfhfgjsegrtd erredtvdejnecuhfhrohhmpedftfhofigrnhcuvfhomhhmihhnshculgfkoffuohfrngdf uceoihhmshhophdrphhhphesrhifvggtrdgtohdruhhkqeenucggtffrrghtthgvrhhnpe ehteelieeigfeuudeiueeiffdvveehudeufeekjeeugffffedtiedtgeettdelteenucev lhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehimhhsohhprd hphhhpsehrfigvtgdrtghordhukh X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Tue, 2 Apr 2024 16:10:39 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------CA6P0Eq3Ss680KHgjtM0011A" Message-ID: Date: Tue, 2 Apr 2024 21:10:38 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [RFC][Concept] Data classes (a.k.a. structs) To: internals@lists.php.net References: Content-Language: en-GB In-Reply-To: From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------CA6P0Eq3Ss680KHgjtM0011A Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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] --------------CA6P0Eq3Ss680KHgjtM0011A Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit
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]
--------------CA6P0Eq3Ss680KHgjtM0011A--