Re: Custom object equality

From: Date: Wed, 18 Oct 2023 13:12:34 +0000
Subject: Re: Custom object equality
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-121391@lists.php.net to get a copy of this message
On Wed, Oct 18, 2023 at 2:51 PM someniatko <someniatko@gmail.com> 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 objects are > involved. For instance, Money has an amount and a currency. > > There were already suggestions on the mailing list to allow "overloading" > existing == operator, and some suggestions went even as far as > overloading <, >= etc > operators. However, overloading existing > operators may lead to a BC break between the PHP version which does support > the functionality, and which doesn't. It won't result in a BC break in case > it's an entirely new syntax, because a library or a project won't be able > to write code which overloads == 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 == will work differently > for 8.3 and > 8.4. > > I suggest thinking about introducing a new operator ~=, which > signifies > that custom equality is requested. In such a case, == will > work as it > works now, and by default ~= will work also like > ==, unless its > behavior is overwritten via a magic method. If a magic method is not > present in a class being compared, ~= will compare two objects > field by > field, but using ~= comparison rather than > == comparison, recursively. > > For instance, a Money object may consist of Amount and Currency. If two > Moneys are compared using ~=, and Money does not implement a > magic > method, Amount also doesn't implement it, but Currency does, then Amounts > are compared using ~= which is equal to > == comparison in this case, > but Currencies are compared using their custom comparison logic. > > This approach allows combining > - no BC break - ~= is a new syntax which is unavailable in > older PHP > versions > - explicitly showing an intent that objects are compared using a custom > comparison, rather than standard PHP one > - allow to skip writing boilerplate equals() methods which just forward > equals() to the nested objects > - standardize such comparisons on the language level > > Of course how exactly this operator looks may be changed, ~= is > just 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 ~<, ~<=, ~!, ~= which can 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

« previous php.internals (#121391) next »