Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:121408 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 96047 invoked from network); 18 Oct 2023 16:43:18 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 18 Oct 2023 16:43:18 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 72EB81804BC for ; Wed, 18 Oct 2023 09:43:17 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS29838 64.147.123.0/24 X-Spam-Virus: No X-Envelope-From: Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 18 Oct 2023 09:43:16 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id C2DC13200BA3 for ; Wed, 18 Oct 2023 12:43:15 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute1.internal (MEProxy); Wed, 18 Oct 2023 12:43:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm3; t=1697647395; x=1697733795; bh=/vEdELK9bQ o73HzArj+yralnCPl61mrjurJt7LpWnvA=; b=XUKBOnrdSTXAAVQLtj2M0ttHIa 0sONv9p6cUrv5E/3pGnIzsIBj+XRP2f/rcs4ys6ZYZzavQlF3kTgmleYO5wwVNbX Lplr1BdYvU6eYqWcTRdgy2sN+IE8kOf2n+/tApr4XIaFkENylAmZK8e6QwPWe1pB Y3iHZxpfkfts/KZKpI1TdwRmn6oWYV+QkHzwdXhsb1a773a+nc9gcI5+7xPvmx+m 4+KWHCzesV0HRHY5dIez4wriCJ4LmVDXZIrlNbqkYtBGLOXn5JS3g8gy05MVHNfS LMga93Ph2unKBmYY9Z91Hiv/wv236ADCNNO79D54TPbF7MFPdEVcqifwsxzA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding: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:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1697647395; x= 1697733795; bh=/vEdELK9bQo73HzArj+yralnCPl61mrjurJt7LpWnvA=; b=C dwg1AfEB74FLBr/603iyCmgcx8AwOZvyInp3qZKKjDT9YKxRz5DHQPV+UzyVNmYp tSBJIBk03uBU/PgfcmdYpgYIp2dvBtnOT1DZ5aPlwTje4B2YdEUDIFHEcULi+znd 2dkLruvosyfn9axDz7TxpBOHf7RgBoqcbBaRdmO6f6wbsc59XeCWCkSFQSI2kTbi D8pPRRcZF/PFVPAK5JyW9k8TdK4QaBjFX8MDRggqyLLKwqcavn6+oppNXI47C9cK M9RdKA8X7QUIh0X+EZaoQDHwwg+chMtLBzf/t4wnjORmy0niXv9EalnDdGJtiiPn jVNT4WEk9n/VD40oNdkyQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrjeeggddutddvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepfeegledujeevveevteevvdetudejiefguddttddt vdeghfduteethfffgfehjeehnecuffhomhgrihhnpehprggtkhgrghhishhtrdhorhhgne cuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheplhgrrhhr hiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id DCBEF1700090; Wed, 18 Oct 2023 12:43:14 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-1019-ged83ad8595-fm-20231002.001-ged83ad85 MIME-Version: 1.0 Message-ID: In-Reply-To: References: Date: Wed, 18 Oct 2023 16:42:53 +0000 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Custom object equality From: larry@garfieldtech.com ("Larry Garfield") On Wed, Oct 18, 2023, at 1:12 PM, Robert Landers wrote: > On Wed, Oct 18, 2023 at 2:51=E2=80=AFPM someniatko wrote: >> >> Hi internals, >> >> There is often a need to compare whether two objects are equal. For >> example, a popular [brick/money](https://packagist.org/packages/brick= /money) >> library has a `Money` class, which has an `equals()` method. However,= this >> becomes tedious to implement such methods, when multiple nested objec= ts are >> involved. For instance, Money has an amount and a currency. >> >> There were already suggestions on the mailing list to allow "overload= ing" >> existing `=3D=3D` operator, and some suggestions went even as far as >> overloading `<`, `>=3D` etc operators. However, overloading existing >> operators may lead to a BC break between the PHP version which does s= upport >> the functionality, and which doesn't. It won't result in a BC break i= n case >> it's an entirely new syntax, because a library or a project won't be = able >> to write code which overloads `=3D=3D` in say PHP 8.4, but with code = which >> still works in PHP 8.3 - it will have to require PHP 8.4+. But if it = is >> implemented as a magic method, then `=3D=3D` will work differently fo= r 8.3 and >> 8.4. >> >> I suggest thinking about introducing a new operator `~=3D`, which sig= nifies >> that custom equality is requested. In such a case, `=3D=3D` will wor= k as it >> works now, and by default `~=3D` will work also like `=3D=3D`, unless= its >> behavior is overwritten via a magic method. If a magic method is not >> present in a class being compared, `~=3D` will compare two objects fi= eld by >> field, but using `~=3D` comparison rather than `=3D=3D` comparison, r= ecursively. >> >> For instance, a Money object may consist of Amount and Currency. If t= wo >> Moneys are compared using `~=3D`, and Money does not implement a magic >> method, Amount also doesn't implement it, but Currency does, then Amo= unts >> are compared using `~=3D` which is equal to `=3D=3D` comparison in t= his case, >> but Currencies are compared using their custom comparison logic. >> >> This approach allows combining >> - no BC break - `~=3D` is a new syntax which is unavailable in older = PHP >> versions >> - explicitly showing an intent that objects are compared using a cust= om >> comparison, rather than standard PHP one >> - allow to skip writing boilerplate equals() methods which just forwa= rd >> equals() to the nested objects >> - standardize such comparisons on the language level >> >> Of course how exactly this operator looks may be changed, `~=3D` is j= ust an >> example. >> >> WDYT? >> >> Regards, >> Illia / someniatko > > I like it. > > One thing I really like about this proposal is that, in theory, it > could open the door to new operators like ~<, ~<=3D, ~!, ~=3D which ca= n be > similarly implemented. > > It also makes me wonder if something similar to scala can be > implemented, where any operator beginning with "~" can just call an > associated magic method. I'm not sure how it would be implemented > though, since I don't think you can use symbols/operators in method > names. But if you wanted a pipe operator, you could add one via ~|. > It'd allow for more useful DSL's that are implemented in PHP, as > currently, it doesn't really make sense to create a DSL that is > actually PHP since you can't override any operators. > > That being said, my only criticism is that it will be really easy to > forget the ~ when writing code. It's a true shame that overloading > wasn't added to the language, as it makes it an impractical language > for entire classes of problems/solutions. > > Robert Landers > Software Engineer > Utrecht NL Honestly I'm still on team operator-override. *Most* major languages ha= ve operator overloading, and it doesn't seem to cause a problem. (Accor= ding to my research, C++, Kotlin, Swift, Rust, C#, Haskell, Python, and = Ruby all have operator overloading. Go, TypeScript, PHP, and Javascript= do not. Java has comparison-only overloading so it's in the middle.) = Most of the "it causes so many problems" arguments are, from what I can = tell, greatly over-exaggerated. More to the point, the key question is whether anyone who voted No on th= e previous operator overloading RFC would vote Yes on an operator-overlo= ading-but-only-with-an-opt-in-prefix RFC. If not, then it doesn't reall= y buy us anything. If so, then it's possible as a compromise but would,= frankly, be strictly inferior to just using the native operators we alr= eady have. So the real question is: Would anyone who voted No on operator overloadi= ng before vote Yes on it if it used ~=3D, ~>, ~+, etc. instead? ---Larry Garfield