Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123005 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 9E8BE1A009C for ; Sat, 6 Apr 2024 17:56:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712426214; bh=Tf9Pp2CjbXuy9DzX3Bj7oo3wffJPOc5Fa9SOQaEtMFI=; h=References:In-Reply-To:From:Date:Subject:To:From; b=R7TUYeDbvkU0lngEicshHED2/rK62pFBSnl9kfVWQn4vknSZcBpAVOj9Z4KtydNUr sJNeKNVzCE1eufPPkc4qynOtpUh0V0QDjqtWdaLHLnAUbxkHBkzGrjZlBVdBtIlpm2 RfXuh1Yn+gI2v906OcRE/CZJ0OKl5x2CO7Zsm5UR1BQ9BoMWElKj/Sgz8DFf+1uLe5 AfyTSau0MpNaLkjJR2VL4HsMdIbsleGqGqFhkciVlkBTuqOVFwGnwzrnKybk+B4e6B UzI5Z2lDRJnBC5PdXIIjpDqVd+MJ1Dngi78obJWB5MXauFSBru+do4Wu9FchykXl6U hPrNHIJuMXCMA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E9BC9180068 for ; Sat, 6 Apr 2024 17:56:53 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,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 mail-qv1-f44.google.com (mail-qv1-f44.google.com [209.85.219.44]) (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 ; Sat, 6 Apr 2024 17:56:53 +0000 (UTC) Received: by mail-qv1-f44.google.com with SMTP id 6a1803df08f44-699320fcbc1so17384196d6.3 for ; Sat, 06 Apr 2024 10:56:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712426182; x=1713030982; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=Tf9Pp2CjbXuy9DzX3Bj7oo3wffJPOc5Fa9SOQaEtMFI=; b=S19YCjxoq+dUGXmeMvudQQ66/I6M41NGxvTmCMRRu3AEFRfWpVKL1O/JWbRXf1Iry1 540YUzRJT5e/2f+zPFJVpDMAeOnGwKp0kWGX0zlNhC4yWa4862ELb3He5APo9Fry8uEe BKnxI/00V79FNA81N1RYjGa8vw4E1Kann2BY3cTUJOxJ73+QdhPFJJqnIh6f6Vdmnk7W 3JbRxKdBC/XNT1OeouuewXJHS4HEmjEuDcy657tVchzaGHmjQwDsyrR5IXCDeINfMEfK 68Bqco56JYPKIDpmxiLzIv7Z4JMk/3/f2nA1GG1zcCiof8t5UnY0J1sL5RlMDhu8DhKl fviw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712426182; x=1713030982; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Tf9Pp2CjbXuy9DzX3Bj7oo3wffJPOc5Fa9SOQaEtMFI=; b=lMc8O8ocXh1N77yvCiwCXBYBAb+7HTgbLIobLVbyC6zSFvwKp/PoOQV5n3gniv9FQK rtSlWIInY75izt6QokilJrKI4h8eG6N8u/hq6OT3eoH0hU4O9hWt5nwIQcqHZ8qaQtc+ JIGS75ZtB/bYmbyYaCdg0ENKqedNs+ShXaNUworP3UWU4Pkob3rLGkUxCj37rkxqEKKC hr+1uNpcHmrc2rI07fdc69ZcSeWLB6L3D93skrWy45PlstRkiFGgvt6x6t8Fp7XLnv7t fh04WrmlVGaJZ6Zwhy61T4FKca9SAkoexlIevreaYFz876FL0vANxena755OGTTpSSLp vmVw== X-Gm-Message-State: AOJu0YzEqjZAbKVJ97TEBzT2ZmPJ9A619GJo0Nl4n3M1SxaYed0hTHlw sMbEzcizzKy/wdEji7CfidLjetxuUOMn+mKg/tsRZX66C8QN0UZ+zzDCjWwXxkMpIdBwFpmKitO KReaDrwjkAQ9CZlKgCJ7ShaNC2MgrSk+v0JZ64g== X-Google-Smtp-Source: AGHT+IHAT5IJhQAOhtkj7yJ4CxJYzmrzqt6sYnzQMiikClkfJfv1BH/WgfI2aMucSu77YMxP7dK2Qu5SAReNs6dZhz0= X-Received: by 2002:ad4:5c6f:0:b0:699:b34:783f with SMTP id i15-20020ad45c6f000000b006990b34783fmr4884399qvh.62.1712426181802; Sat, 06 Apr 2024 10:56:21 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <9f66fd2b-d93e-42d1-906a-ca83cc51b08e@rwec.co.uk> In-Reply-To: <9f66fd2b-d93e-42d1-906a-ca83cc51b08e@rwec.co.uk> Date: Sat, 6 Apr 2024 19:56:11 +0200 Message-ID: Subject: Re: [PHP-DEV] [RFC][Concept] Data classes (a.k.a. structs) To: PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi Rowan On Fri, Apr 5, 2024 at 12:28=E2=80=AFAM Rowan Tommins [IMSoP] wrote: > > On 03/04/2024 00:01, Ilija Tovilo wrote: > > Regardless of the implementation, there are a lot of interactions we will= want to consider; and we will have to keep considering new ones as we add = to the language. For instance, the Property Hooks RFC would probably have n= eeded a section on "Interaction with Data Classes". That remark was implying that data classes really are just classes with some additional tweaks. That gives us the ability to handle them differently when desired. However, they will otherwise behave just like classes, which makes it not so different from your suggestion. > On a practical note, a few things I've already thought of to consider: > > - Can a data class have readonly properties (or be marked "readonly data = class")? If so, how will they behave? Yes. The CoW semantics become irrelevant, given that nothing may trigger a separation. However, data classes also include value equality, and hashing in the future. These may still be useful for immutable data. > - Can you explicitly use the "clone" keyword with an instance of a data c= lass? Does it make any difference? Manual cloning is not useful, but it's also not harmful. So I'm leaning towards allowing this. This way, data classes may be handled generically, along with other non-data classes. > - Tied into that: can you implement __clone(), and when will it be called= ? Yes. `__clone` will be called when the object is separated, as you would ex= pect. > - If you implement __set(), will copy-on-write be triggered before it's c= alled? Yes. Separation happens as part of the property fetching, rather than the assignment itself. Hence, for `$foo->bar->baz =3D 'baz';`, once `Bar::__set('baz', 'baz')` is called, `$foo` and `$foo->bar` will already have been separated. > - Can you implement __destruct()? Will it ever be called? Yes. As with any other object, this will be called once the last reference to the object goes away. There's nothing special going on. It's worth noting that CoW makes `__clone` and `__destruct` somewhat nondeterministic, or at least non-obvious. > > Consider this example, which would > work with the current approach: > = > $shapes[0]->position->zero!(); > > I find this concise example confusing, and I think there's a few things t= o unpack here... I think you're putting too much focus on CoW. CoW should really be considered an implementation detail. It's not _fully_ transparent, given that it is observable through `__clone` and `__destruct` as mentioned above. But it is _mostly_ transparent. Conceptually, the copy happens not when the method is called, but when the variable is assigned. For your example: ```php $shape =3D new Shape(new Position(42,42)); $copy =3D $shape; // Conceptually, a recursive copy happens here. $copy->position->zero!(); // $shape is already detached from $copy. The ! merely indicates that the value is modified. ``` > The array access doesn't need any special marker, because there's no ambi= guity. This is only true if you ignore ArrayAccess. `$foo['bar']` does not necessarily indicate that `$foo` is an array. If it were a `Vector`, then we would absolutely need an indication to separate it. It's true that `$foo->bar` currently indicates that `$foo` is a reference type. This assumption would break with this RFC, but that's also kind of the whole point. > What is going to be CoW cloned, and what is going to be modified in place= ? I can't actually know without knowing the definition behind both $item an= d $item->shape. It might even vary depending on input. For the most part, data classes should consist of other value types, or immutable reference types (e.g. DateTimeImmutable). This actually makes the rules quite simple: If you assign a value type, the entire data structure is copied recursively. The fact that PHP delays this step for performance is unimportant. The fact that immutable reference types aren't cloned is also unimportant, given that they don't change. Ilija