Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122885 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 2F2F91A009C for ; Tue, 2 Apr 2024 18:05:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712081135; bh=ofqXgRgPURBVyXp6c9mp80RX5B73spGLX91gFvtyniI=; h=References:In-Reply-To:From:Date:Subject:To:From; b=RJ6pqi0PV3hsgfgfwJkrUAcOowdhZPt0NUr6Aty8NTa/T31KxdVVIAm9ZPmjKTKOF g686D7pfksFnWcAd2UjPb3RUaFevIylXCgOgtndlm8gbbsQnaHEgFVzaAQ6VIdi4eE XrCW45LZs7Rv8Ku1VU+ZOsunVevn2g08GkUuUVXdZ8C8+nptYTZkfnzTrivPb2wIZ7 Rc558WS4nYvWyoTmGAc79ftj/Olsj7Yi9uyW36ENaPWpJe3MnJjwE03/lgSlulnqdz m7auFRzos34yJMk8a1GCoKBQPRSgUreSkd99Vov/1o90hq1gTfHHycYTmGuDv1q+TO 8VKXxakjkOpqA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 820A0180C59 for ; Tue, 2 Apr 2024 18:05:34 +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-qk1-f174.google.com (mail-qk1-f174.google.com [209.85.222.174]) (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 18:05:34 +0000 (UTC) Received: by mail-qk1-f174.google.com with SMTP id af79cd13be357-789f00aba19so415365385a.0 for ; Tue, 02 Apr 2024 11:05:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712081105; x=1712685905; 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=Y1Doe99TJlB9YhsNZ9Yz9QEthxOtJ6+wHJ7SUebLhrg=; b=NkTSjJdjj7MEf2U1S379LPGLU8kB8a4eVuMp3/lG9+ZxZHcynH+BalNB1EFGLioHxn 2VFVfw5h0tpkNvajOHX5rtaRhW9oQ3jlt9GE9sRmsrqSVCvxINWAAGwv3g0FjaFm1XFM vm+ab20BCF3LLBzsHGSBm/95uiHggpyL33OX3p7Y5nCaunfRpp815uFHNYwZIcU0s4Bz SIkGj8vS0zRa04QRRdZnzNw27A2FDASu5s3FGdwK1LVLyPhlhS3FyCs910yQQj2xUeC3 ifMUmvMmEOwyOnZqsvpFopCT/0uIw97HVv/SDhVB0avcSlteLZ2L/47o8YkpAWgwVRrw wfGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712081105; x=1712685905; 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=Y1Doe99TJlB9YhsNZ9Yz9QEthxOtJ6+wHJ7SUebLhrg=; b=HxKV4DeVAx2q57KC3vqCO7L/wU0xNWxZ3YlmuLGkfdsMjjaGf8duHS6FSoJb3Ggp6N UrZt7kTSWQpPYwAVWng7a9CjrN7Mizh7+ue9bheLUcLka97LVVTNJKZS70D86dtKGaJY Zgo6sBIxKxQWF974IDFLdNWhoy8W19R6LNEZKqzSKSUiQ1p2ZovqbDLUgfKqUoONhBxY tGtEPRfeFq6ZtVR2UvN057mV/0p3e2G6gMVpA34YNi/xI+s0MvC0rwc7bv7R3lrYtrYT rXnvQxWyVA/H7CDUBR0uyaUvNicYYV09gvguS9z1dUQf9ONks7lj0KxReffbUeW5/Cb7 +YAQ== X-Gm-Message-State: AOJu0Yw4ugtqcURc4PwdXjsgL5zHcmFBaAwlT5Hm5vBzbBjbN4X2DnMh 5Gy03uxkNnxCekdcngLlNVEGWYN5+AQHwXmlL5QhAmYRJNB7ZZM21o4p+AwZjnnL3fnhdAt4HFu /absYWeLZvTiIRnXB8V0b29n0Iwlk+pODDUYuZEMQ X-Google-Smtp-Source: AGHT+IFNsXdng+yDlZWCeHpYu9H7O/EzymsPh+pHYNQZKsy2F4g9f7Mvk1VLIrsTIr7RmhqCEacBDkegv2/qkhwPj0A= X-Received: by 2002:a0c:f0d3:0:b0:698:70ac:aa51 with SMTP id d19-20020a0cf0d3000000b0069870acaa51mr593774qvl.20.1712081104965; Tue, 02 Apr 2024 11:05:04 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <1a4a44c5-d4f5-40ca-b3dc-13d64c2b4425@app.fastmail.com> In-Reply-To: <1a4a44c5-d4f5-40ca-b3dc-13d64c2b4425@app.fastmail.com> Date: Tue, 2 Apr 2024 20:04:53 +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 Larry On Tue, Apr 2, 2024 at 5:31=E2=80=AFPM Larry Garfield wrote: > > On Tue, Apr 2, 2024, at 12:17 AM, Ilija Tovilo wrote: > > Hi everyone! > > > > 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#). > > > > * Data classes are ordinary classes, and as such may implement > > interfaces, methods and more. I have not decided whether they should > > support inheritance. > > What would be the reason not to? As you indicated in another reply, the = main reason some languages don't is to avoid large stack copies, but PHP do= esn't have large stack copies for objects anyway so that's a non-issue. > > I've long argued that the fewer differences there are between service cla= sses and data classes, the better, so I'm not sure what advantage this woul= d have other than "ugh, inheritance is such a mess" (which is true, but tha= t ship sailed long ago). One issue that just came to mind is object identity. For example: class Person { public function __construct( public string $firstname, public string $lastname, ) {} } class Manager extends Person { public function bossAround() {} } $person =3D new Person('Boss', 'Man'); $manager =3D new Manager('Boss', 'Man'); var_dump($person =3D=3D=3D $manager); // ??? Equality for data objects is based on data, rather than the object handle. How does this interact with inheritance? Technically, Person and Manager represent the same data. Manager contains additional behavior, but does that change identity? I'm not sure what the answer is. That's just the first thing that came to mind. I'm confident we'll discover more such edge cases. Of course, I can invest the time to find the questions before deciding to disallow inheritance. > > * Mutating method calls on data classes use a slightly different > > syntax: `$vector->append!(42)`. All methods mutating `$this` must be > > marked as `mutating`. The reason for this is twofold: 1. It signals to > > the caller that the value is modified. 2. It allows `$vector` to be > > cloned before knowing whether the method `append` is modifying, which > > hugely reduces implementation complexity in the engine. > > As discussed in R11, it would be very beneficial if this marker could be = on the method definition, not the method invocation. You indicated that wo= uld be Hard(tm), but I think it's worth some effort to see if it's surmount= ably hard. (Or at least less hard than just auto-detecting it, which you i= ndicated is Extremely Hard(tm).) I think you misunderstood. The intention is to mark both call-site and declaration. Call-site is marked with ->method!(), while declaration is marked with "public mutating function". Call-site is required to avoid the engine complexity, as previously mentioned. But declaration-site is required so that the user (and IDEs) even know that you need to use the special syntax at the call-site. > So to the extent there is a consensus, equality, stringifying, and a hash= code (which we don't have yet, but will need in the future for some things = I suspect) seem to be the rough expected defaults. I'm just skeptical whether the default __toString() is ever useful. I can see an argument for it for quick debugging in languages that don't provide something like var_dump(). In PHP this seems much less useful. It's impossible to provide a default implementation that works everywhere (or pretty much anywhere, even). Equality is already included. Hashing should be added separately, and probably not just to data classes. > > * In the future, it should be possible to allow using data classes in > > `SplObjectStorage`. However, because hashing is complex, this will be > > postponed to a separate RFC. > > Would data class properties only be allowed to be other data classes, or = could they hold a non-data class? My knee jerk response is they should be = data classes all the way down; the only counter-argument I can think of it = would be how much existing code is out there that is a "data class" in all = but name. I still fear someone adding a DB connection object to a data cla= ss and everything going to hell, though. :-) Disallowing ordinary by-ref objects is not trivial without additional performance penalties, and I don't see a good reason for it. Can you provide an example on when that would be problematic? Ilija