Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122901 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 C03F41A009C for ; Tue, 2 Apr 2024 23:02:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712098960; bh=MpkSbbNMtBPpKV/N9iOYfTxJinoobC4JHGNJRzj3qwA=; h=References:In-Reply-To:From:Date:Subject:To:From; b=ZEXNGCvK6VHwxNfCEFqIt3JArKqygXd6xSk8q3Cy6ZlOpxpiXcnHTrle+exdLWaO8 pvx2uAtpiATnkfmPy1wDvEflax+O8ePUYOjQveg5vf63JayveEh7d6ll6S0VoDCuus FdCTb3pBm20fraXT6rmJ9PagxvTKPGrooOatM6Z/Zz6vuPTis2noeQjlggeY+Wte0X vowZ5ndzD+AvY3z4hTnFhpkTf0/FImV+RDobRmfcLFHRw6X+X33nuCybccH0ovvIqY 8wyJDSPOkMzQ9ZKxohiNHOFr+zvolyY+RYq5ln1FLNi5CTpoIdqPUlZbUlmwZIjhbL f/+lEpwptGPBQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 060B01806EC for ; Tue, 2 Apr 2024 23:02:40 +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_H3,RCVD_IN_MSPIKE_WL,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-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (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 23:02:39 +0000 (UTC) Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-6e69a9c0eaeso3781627a34.3 for ; Tue, 02 Apr 2024 16:02:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712098930; x=1712703730; 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=MpkSbbNMtBPpKV/N9iOYfTxJinoobC4JHGNJRzj3qwA=; b=b9AJB/fieUXvfuooDf0QQgcfbeoVlwW/5cqNCul4nneykWuLDpGbTpq9uXSPNURCmS nnvW88MVLMP1jCt17Ud0Cw1E9dRHbc+gQTN7+EnLAtK7wY7t2bJlpFqUX2BVTiQgQ2Vp 6aA5iGk3tEIV64ecksEuXYP9JHAR2+5gEvRgH56Ha5EhfeWTXlPyP3jTgysZ8AWJNYIR W6kifPrkpNtJOj18Z1fwWcskzDfrnVdmVeNr9IJYhpz19AkHJx7tlMQfAAxOTslIWYRD qDc8Mq7CEIUEh3ZZ0bFCbra/BAhnQgF3DpurtBEsLt2W02R5Sg8QEG1JwS+Mjy/YVlxD nHHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712098930; x=1712703730; 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=MpkSbbNMtBPpKV/N9iOYfTxJinoobC4JHGNJRzj3qwA=; b=U8APTj3rNpQMnenTUAXLKsLPxzBjY8EREOaEjNcFfvQ//8dbYR0yZKonOqMQ3hZuYU iF3oJ4pINTPabm5Kf7MPjkb4Zqmz06FN94WEyhuwU06VO78xDTQtNkWxXXZkLWjiE7UR ePYRtPNyJ9AWa/6agLRrInZhuTFuWYblZQNvucdELIzvGmWPnj9+K9ahfQ4eldIS5rFF nGnDCkm1TB177DvRe+LjH6Y8F6lsxJ6OUzhEoJtip9l6Pl28k3HHObffZe1UXwew4Vsp tAIQUfx5egId2UxWaPS9o0cFtFMfzsh2TsO8qbA8W8/iBapiIUDJwoD/t6zDLAbbgJCi /mJA== X-Gm-Message-State: AOJu0YxzAhWBrjvzePiD/MJXCEDgN8Bpf7tyriR2h1/xvZuF836k1oQ0 wEfphgLGS0dROhoJWkuJtyTfY3BR3VHdfmDkGDKgkr+AYLTUgFRygAH3JXc/+NKgclvoGuKU2o+ dq2EetlKHDB8NutnYaWIHDG7MC2+YsfkZ5sjPKPmC X-Google-Smtp-Source: AGHT+IH0uJxYF21m7WVH7gjM5zSe/Zp0PRRw/MtJonKK9wtO7po4WqV5rkcvNpxI3CotGzyJb3X4SXGQrwi+qH5MMoM= X-Received: by 2002:a05:6870:5314:b0:22a:a167:50fe with SMTP id j20-20020a056870531400b0022aa16750femr16443263oan.3.1712098929953; Tue, 02 Apr 2024 16:02:09 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 3 Apr 2024 01:01:58 +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 Tue, Apr 2, 2024 at 10:10=E2=80=AFPM Rowan Tommins [IMSoP] wrote: > > 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#). > > 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 r= eturn type slot). Otherwise, someone is bound to write this: > > $start =3D new Location('Here'); > $end =3D $start->move!('There'); > > Expecting it to mean this: > > $start =3D new Location('Here'); > $end =3D $start; > $end->move!('There'); > > When it would actually mean this: > > $start =3D new Location('Here'); > $start->move!('There'); > $end =3D $start; I think there are some valid patterns for mutating methods with a return value. For example, Set::add() might return a bool to indicate whether the value was already present in the set. > I seem to remember when this was discussed before, the argument being mad= e that separating value objects completely means you have to spend time dec= iding how they interact with every feature of the language. Data classes are classes with a single additional zend_class_entry.ce_flags flag. So unless customized, they behave as classes. This way, we have the option to tweak any behavior we would like, but we don't need to. Of course, this will still require an analysis of what behavior we might want to tweak. > 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-si= te marker slightly to a ->! operator: > > $foo->!mutate(); > $foo->!bar =3D 42; I suppose this is possible, but it puts the burden for figuring out what to separate onto the user. Consider this example, which would work with the current approach: $shapes[0]->position->zero!(); The left-hand-side of the mutating method call is fetched by "read+write". Essentially, this ensures that any array or data class is separated (copied if RC >1). Without such a class-wide marker, you'll need to remember to add the special syntax exactly where applicable. $shapes![0]!->position!->zero(); In this case, $shapes, $shapes[0], and $shapes[0]->position must all be separated. This seems very easy to mess up, especially since only zero() is actually known to be separating and can thus be verified at runtime. > The main drawback I can see (outside of the implementation, which I can't= comment on) is that we couldn't overload the =3D=3D=3D operator to use val= ue 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. Right, this would either require some other marker that switches to this mode of comparison, or operator overloading. Ilija