Re: [PHP-DEV] Custom object equality
I am just going to put this out there, but I will vote against any RFC which provides access to userland to overload == and <=> until the base semantics of PHP comparisons are fixed and the necessary engine prerequisite work is done. I am working on such an RFC, as I frankly do not trust people to think stuff through and handle things like polymorphic comparisons. Also, introducing some new kind of weird operator is just... bad. Best regards, George P. Banyard
Re: [PHP-DEV] Custom object equality
On 23-10-2023 22:07, Jordan LeDoux wrote: I don't quite follow. The interface would cause the engine to use the result of an `equals()` function on the object if it implements an interface as part of `zend_compare`? Internally there is no `==` function, there is only the equivalent of `<=>`. To implement it ONLY for `==` would require a trapdoor of some kind in the `do_operation` handler that would also affect the way the existing extensions work, such as the `DateTime` class which implements a custom handler for the `compare` handler on the zend class entry. No, the interface would not cause anything to happen in `zend_compare`. It would simply serve to make explicit that an object has a custom implementation of a (set of) operators and that the implementing method can be called directly. So the developer can choose to either use the operator or call the implementing method on the object. Both styles would be supported and the following two expressions would be equivalent: $a == $b $a->equals($b) (the method name is just an example) Regarding your (Jordan's) RFC on the subject: The method call style would not yield readable code in this case, as the 'methods' are named after the operators. So that part of the RFC would need to change to make both styles work. Regards, Dik -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
Hi Jordan, On 23.10.23 22:07, Jordan LeDoux wrote: Implementing the compare handler for an overload requires adding two new entries to ZEND_AST_BINARY_OP because the `>` and `<` comparisons have to be preserved in the AST in order to call the correct object handler. THAT requires updating OpCache and JIT since all such comparisons are currently reordered to use `<`, and though I spent quite a while looking at it, I think Dmitry might be the only person that could really implement that fully. At least, I never found anyone that had the expertise to actually help me with it. 17 years ago Sara was working on it, too ;) https://externals.io/message/21883 Jordan Best, Marc OpenPGP_0x3936ABF753BC88CE.asc Description: OpenPGP public key OpenPGP_signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Custom object equality
On Mon, Oct 23, 2023 at 10:20 AM Dik Takken wrote: > On 23-10-2023 18:34, Larry Garfield wrote: > > > > Jordan's RFC explained in detail why interfaces are not viable, which is > why we have to use magic methods (with or without a special keyword) > instead: > > > > > https://wiki.php.net/rfc/user_defined_operator_overloads#why_not_interfaces > > > > (Seriously, it has an extensive FAQ. It's one of the more detailed and > supported RFCs we've seen.) > > > > Yes, I know the RFC, it's a great piece of work! The use of interfaces > as mentioned in this RFC is however completely different from what > Pierre and I are talking about. If I understand Pierre correctly, that > is. The suggestion to include interfaces simply meant to allow freedom > of choice. Choice between using an operator (`==`) or calling the > equivalent method on the object (`->equals()`). That may get more people > on board with operator overloading. > > Regards, > Dik > > I don't quite follow. The interface would cause the engine to use the result of an `equals()` function on the object if it implements an interface as part of `zend_compare`? Internally there is no `==` function, there is only the equivalent of `<=>`. To implement it ONLY for `==` would require a trapdoor of some kind in the `do_operation` handler that would also affect the way the existing extensions work, such as the `DateTime` class which implements a custom handler for the `compare` handler on the zend class entry. This might be easier to do once a few comparison improvements to separate "comparable" and "equatable" are done, but the PR I submitted two years ago to handle that got kind of mired in bike shedding about the implementation and I lost interest in continuing to push it. Implementing the compare handler for an overload requires adding two new entries to ZEND_AST_BINARY_OP because the `>` and `<` comparisons have to be preserved in the AST in order to call the correct object handler. THAT requires updating OpCache and JIT since all such comparisons are currently reordered to use `<`, and though I spent quite a while looking at it, I think Dmitry might be the only person that could really implement that fully. At least, I never found anyone that had the expertise to actually help me with it. Jordan
Re: [PHP-DEV] Custom object equality
On 23-10-2023 18:34, Larry Garfield wrote: Jordan's RFC explained in detail why interfaces are not viable, which is why we have to use magic methods (with or without a special keyword) instead: https://wiki.php.net/rfc/user_defined_operator_overloads#why_not_interfaces (Seriously, it has an extensive FAQ. It's one of the more detailed and supported RFCs we've seen.) Yes, I know the RFC, it's a great piece of work! The use of interfaces as mentioned in this RFC is however completely different from what Pierre and I are talking about. If I understand Pierre correctly, that is. The suggestion to include interfaces simply meant to allow freedom of choice. Choice between using an operator (`==`) or calling the equivalent method on the object (`->equals()`). That may get more people on board with operator overloading. Regards, Dik -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Mon, Oct 23, 2023, at 3:14 PM, Dik Takken wrote: > On 18-10-2023 14:50, someniatko wrote: >> 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 >> > > One thing to keep in mind is that operator overloading already exists in > PHP. And it is already in use in userland PHP too, for example when > comparing DateTime objects. The limitation is that it only works for > some objects: Those that are implemented in an extension. > > To me, the obvious way forward would be to lift this limitation. But... > several attempts to do so have failed to pass. People are hesitant to > unleash full operator overloading power to PHP developers. > > So, perhaps a simplified version of the RFC by Jordan LeDoux, limited to > the `==` operator only, would stand a chance? It would allow the > community to try their hands on this one (highly valuable) operator > overload. PHP 9 is coming and provides a great opportunity. > > I also like the idea from Pierre to provide interfaces. Some people > prefer an explicit method call over an operator doing magic things, > which I fully understand. Perhaps we could allow both? > > Regards, > Dik I would recommend including ==, <, >, <=, >= all in the initial design, as they do interact. I've said in the past that I'd welcome a reduced-scope version as a stepping stone. Jordan's RFC explained in detail why interfaces are not viable, which is why we have to use magic methods (with or without a special keyword) instead: https://wiki.php.net/rfc/user_defined_operator_overloads#why_not_interfaces (Seriously, it has an extensive FAQ. It's one of the more detailed and supported RFCs we've seen.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On 18-10-2023 14:50, someniatko wrote: 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 One thing to keep in mind is that operator overloading already exists in PHP. And it is already in use in userland PHP too, for example when comparing DateTime objects. The limitation is that it only works for some objects: Those that are implemented in an extension. To me, the obvious way forward would be to lift this limitation. But... several attempts to do so have failed to pass. People are hesitant to unleash full operator overloading power to PHP developers. So, perhaps a simplified version of the RFC by Jordan LeDoux, limited to the `==` operator only, would stand a chance? It would allow the community to try their hands on this one (highly valuable) operator overload. PHP 9 is coming and provides a great opportunity. I also like the idea from Pierre to provide interfaces. Some people prefer an explicit method call over an operator doing magic things, which I fully understand. Perhaps we could allow both? Regards, Dik -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Thu, Oct 19, 2023 at 12:14 AM Pierre wrote: > > Maybe I don't master english enough and I can speak to strictly > sometime. If an operator overload RFC that doesn't have any blind spot > or weird edge case happens, I'd be happy to see it pass, at least it > would close bike shedding around this topic and life would continue > happily. > > I can't vote, but if I could, I wouldn't vote against a proper, robust, > and easy to debug for developers operator overload RFC, I would simply > abstain, because even if I personally don't like it, lots of people want > it and I'm simply one among millions of PHP users, I don't want anyone > to be frustrated. > > The most important thing in my previous message I wanted to say was that > the "~" symbol refers to something "approximate" in many contexts, in my > opinion it's not the right choice for an equality operator. My opinion > is either go for a full-on proper operator overload or simply don't. > > Regards, > > -- > > Pierre > > I tried to make sure this was clear, but I will say it explicitly just to make sure: I am not at all criticizing you, I was just saying that the opinion you expressed is one that is shared by many voters so it cannot be simply dismissed, and that I disagree with it personally. Jordan
Re: [PHP-DEV] Custom object equality
On 18 Oct 2023, at 13:50, someniatko wrote: > There were already suggestions on the mailing list to allow "overloading" > existing `==` operator, and some suggestions went even as far as overloading > `<`, `>=` etc operators. Slightly off-topic, but concatenation? Just as a possible feature... for my sins I'm the database component maintainer for WordPress, and I'm currently getting `wpdb::prepare()` to work with the `literal-string` type, where I added support for escaping identifiers (field/table names). This function works like `sprintf()`, with the SQL being the `$format` argument, and then user values; from that it returns an SQL string with escaped values (yes, I know, parameterised queries are better, but we work with what we have)... developers often concatenate these together, but I was wondering if I could return a stringable value-object, so when they are concatenated, a new value-object could be created instead, so we can verify (ideally at runtime) that all values have been escaped correctly (and maybe use parameterised queries). Craig -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On 10/18/23 20:20, Lanre Waju wrote: I believe it's time to shift our focus away from backward compatibility (BC) concerns in major versions. In my opinion, genuine operator overloading is incomparable to the pseudo operator. I genuinely see the operator overloads as an invaluable addition to PHP 9 Lanre I definitely agree with everything you wrote with enthusiastic attitude. Less BC could lead to awesome improvements in the future. PHP version checks could be added to applications instead then. pixel -- phone: ++49 / (0)172 / 44 1 88 56 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
Le 18/10/2023 à 22:22, Jordan LeDoux a écrit : While I (obviously) appreciate the goal of the proposal here since I wrote the gigantic operator overload RFC the last time it was proposed, I do not support this idea here for one very simple reason: it is a clunky, work-around implementation to try and get the benefits of operator overloads without actually doing it. Even if I don't really like operator overload, I would very much prefer the gigantic operator overload to pass than a band-aid patch with a new operator, I'm all in for consistency. The need to control comparisons is real and obvious. So long as voters are categorically opposed to actual operator overloads no matter the implementation, as represented here by you Pierre but by no means a position that only you hold, I don't think we should be looking for ways to get the functionality through hacks like this. It may get passed in the short term and get PHP developers the equality comparison control that objects desperately need, but it makes all future improvements almost impossible to do. Maybe I don't master english enough and I can speak to strictly sometime. If an operator overload RFC that doesn't have any blind spot or weird edge case happens, I'd be happy to see it pass, at least it would close bike shedding around this topic and life would continue happily. I can't vote, but if I could, I wouldn't vote against a proper, robust, and easy to debug for developers operator overload RFC, I would simply abstain, because even if I personally don't like it, lots of people want it and I'm simply one among millions of PHP users, I don't want anyone to be frustrated. The most important thing in my previous message I wanted to say was that the "~" symbol refers to something "approximate" in many contexts, in my opinion it's not the right choice for an equality operator. My opinion is either go for a full-on proper operator overload or simply don't. Regards, -- Pierre
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 10:22 PM Jordan LeDoux wrote: > > On Wed, Oct 18, 2023 at 6:03 AM Pierre wrote: > > > Le 18/10/2023 à 14:50, someniatko a écrit : > > > Hi internals, > > > > > > 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? > > > > I'm not fond of operator overloading, I actually quite hate it, I like > > the expressiveness of an equals() method. > > > > I would very much prefer to have a set of standard interfaces such as > > Comparable { compareTo($other): int } or Equatable { equals($other): > > bool; } which the standard API and userland libraries could make use of. > > > > In all cases, I don't like the ~= choice because in my mind it literally > > translates to "is approximately/barely/maybe comparable to". > > > > By the way, please do not use abbreviations such as WDYT, I'm not a > > native english speaker and I don't know all abbreviations, I had to > > duckduckgo' it. > > > > Regards, > > > > -- > > > > Pierre > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > > While I (obviously) appreciate the goal of the proposal here since I wrote > the gigantic operator overload RFC the last time it was proposed, I do not > support this idea here for one very simple reason: it is a clunky, > work-around implementation to try and get the benefits of operator > overloads without actually doing it. > > The need to control comparisons is real and obvious. So long as voters are > categorically opposed to actual operator overloads no matter the > implementation, as represented here by you Pierre but by no means a > position that only you hold, I don't think we should be looking for ways to > get the functionality through hacks like this. It may get passed in the > short term and get PHP developers the equality comparison control that > objects desperately need, but it makes all future improvements almost > impossible to do. > > someniatko: > > If voters don't want operator overloads, then voters don't get the features > of operator overloads. It's very much that simple. If you want this > feature, try and change minds (ha ha good luck). "Operator overloads don't > fit a language like PHP"... despite the fact that Python is the language > most like PHP in many ways and has some absolutely crazy operator > overloads. "Operator overloads make operators impossible to understand"... > despite the fact that this is already the case with existing operators and > magic methods. "There is no use case"... despite the fact that this gets > suggested by a different person like clockwork AT LEAST every version > because it is something they would use. > > Honestly I would give up on advocating for operator overloads someniatko > and just move to a language that has them like Python. That's what I did. > Your sanity will thank me. > > Jordan As a user of PHP, it was sad to see that fail. There are no "unsigned longs" in PHP, and I had to create a library that emulated them using GMP. There is no way to describe how terrible using that library was... simply because you couldn't overload a plus sign or an equals sign. Accidentally using real operators could cause all kinds of shenanigans and invalid math being done. Fun times. If it had been a possibility, we would have ditched PHP immediately. We almost did anyway, even if it meant rewriting everything. People seem to be hung up on "people might abuse it" and forget there are real-world, somewhat niche problems that are True Pain (TM) to solve without overloading. Pain enough to leave the language entirely. Thank you for your contribution, it was a really well-put-together RFC, IMHO. I would have voted for it if I could have. Robert Landers Software Engineer Utrecht NL -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 6:03 AM Pierre wrote: > Le 18/10/2023 à 14:50, someniatko a écrit : > > Hi internals, > > > > 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? > > I'm not fond of operator overloading, I actually quite hate it, I like > the expressiveness of an equals() method. > > I would very much prefer to have a set of standard interfaces such as > Comparable { compareTo($other): int } or Equatable { equals($other): > bool; } which the standard API and userland libraries could make use of. > > In all cases, I don't like the ~= choice because in my mind it literally > translates to "is approximately/barely/maybe comparable to". > > By the way, please do not use abbreviations such as WDYT, I'm not a > native english speaker and I don't know all abbreviations, I had to > duckduckgo' it. > > Regards, > > -- > > Pierre > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > While I (obviously) appreciate the goal of the proposal here since I wrote the gigantic operator overload RFC the last time it was proposed, I do not support this idea here for one very simple reason: it is a clunky, work-around implementation to try and get the benefits of operator overloads without actually doing it. The need to control comparisons is real and obvious. So long as voters are categorically opposed to actual operator overloads no matter the implementation, as represented here by you Pierre but by no means a position that only you hold, I don't think we should be looking for ways to get the functionality through hacks like this. It may get passed in the short term and get PHP developers the equality comparison control that objects desperately need, but it makes all future improvements almost impossible to do. someniatko: If voters don't want operator overloads, then voters don't get the features of operator overloads. It's very much that simple. If you want this feature, try and change minds (ha ha good luck). "Operator overloads don't fit a language like PHP"... despite the fact that Python is the language most like PHP in many ways and has some absolutely crazy operator overloads. "Operator overloads make operators impossible to understand"... despite the fact that this is already the case with existing operators and magic methods. "There is no use case"... despite the fact that this gets suggested by a different person like clockwork AT LEAST every version because it is something they would use. Honestly I would give up on advocating for operator overloads someniatko and just move to a language that has them like Python. That's what I did. Your sanity will thank me. Jordan
Re: [PHP-DEV] Custom object equality
Hi On 10/18/23 18:42, Larry Garfield wrote: Honestly I'm still on team operator-override. *Most* major languages have operator overloading, and it doesn't seem to cause a problem. (According 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. To clarify here: Haskell does not have operators per se. It has functions whose name may consist of symbols only. It also has function overloading via its typeclass feature (roughly comparable to interfaces). It also allows to write any binary function in infix form by wrapping it into backticks. More to the point, the key question is whether anyone who voted No on the previous operator overloading RFC would vote Yes on an operator-overloading-but-only-with-an-opt-in-prefix RFC. If not, then it doesn't really 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 already have. So the real question is: Would anyone who voted No on operator overloading before vote Yes on it if it used ~=, ~>, ~+, etc. instead? I did not vote, but I would not vote in favor of operator overloading with a different syntax. My main issue with operator overloading via instance methods is that it's too easy to achieve a non-symmetric equality, i.e. `$a == $b` != `$b == $a`. This is a somewhat common problem of Java's `.equals()` method, unless you are careful with how you write the implementation (e.g. https://stackoverflow.com/a/6518645). At least for `.equals()` it would be obvious that it would be an instance method and that it might not be symmetric. Operator overloading is only a value-add to me, if it would be realized via free-standing functions to ensure there is a single canonical implementation for a given operator, instead two different ones with inverted parameter order. And yes, I realize that this would require function overloading. I would be in favor of allowing writing binary functions in infix position to allow stuff like '($foo bcadd 5)', because I can see how that is more readable than `bcadd($foo, 5)` Best regards Tim Düsterhus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
I believe it's time to shift our focus away from backward compatibility (BC) concerns in major versions. In my opinion, genuine operator overloading is incomparable to the pseudo operator. I genuinely see the operator overloads as an invaluable addition to PHP 9 Lanre On 2023-10-18 6:50 a.m., 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 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 2:05 PM Christian Schneider wrote: > Am 18.10.2023 um 18:42 schrieb Larry Garfield : > > So the real question is: Would anyone who voted No on operator > overloading before vote Yes on it if it used ~=, ~>, ~+, etc. instead? > > I confess that I'm not a fan of operator overloading for a language like > PHP but introducing new operators on top of making them overloadable seems > a bad idea. Operators have the problem of being hard to look up and > prefixing them with ~ feels like the worst of both worlds. > > Regards, > - Chris > To add on to this, the proposal side-steps a potential BC break issue while introducing a collection of problems for libraries using PHP Tokens, Static Analysers, IDEs and more importantly the ability to grep your codebase looking for `==`. >From what I understood about the BC break concern, it's the fact that IF: - Existing code is comparing objects (relying on potentially non-deterministic behavior?) - PHP introduces operator overload - A library releases a new major version implementing operator overload - Existing code breaks Sounds to me that this is more between Library authors and Library users. Yes, PHP would be opening the door for potential BC breaks, but the stability of Composer packages and the adoption of Semantic Versioning throughout the industry makes this look like PHP is trying to protect grown, trained, mentally stable adults from running with knives. On Wed, Oct 18, 2023 at 1:43 PM Larry Garfield wrote: > Honestly I'm still on team operator-override. *Most* major languages have > operator overloading, and it doesn't seem to cause a problem. (According > 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. > > ---Larry Garfield > To argue against myself, I think Larry has a killer point in the language comparison. I think it's fair to say PHP is the weird one out for not having Operator Overload when even Python and Ruby (languages more similar to PHP than Kotlin or Rust) have them. Ultimately, if voters think it's best to overload `~=` instead of `==`, I think we bite the bullet and deal with the consequences. Even though I have every reason not to want `~=`, PHP deserves method overloading unless folks can show facts as to why nearly every other major programming language is wrong or why they can have it and we can't. -- Marco Deleu
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 2:51 PM 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 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 > Note that `~=` is used in Lua instead of `!=`. Having this operator be an overloading == would feel really counterintuitive to me. We have "instanceof", and I've seen "is" ideas floating around. Could also look into the direction of "equals" for this. https://www.lua.org/pil/3.2.html
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 7:05 PM Christian Schneider wrote: > > Am 18.10.2023 um 18:42 schrieb Larry Garfield : > > So the real question is: Would anyone who voted No on operator overloading > > before vote Yes on it if it used ~=, ~>, ~+, etc. instead? > > I confess that I'm not a fan of operator overloading for a language like PHP > but introducing new operators on top of making them overloadable seems a bad > idea. Operators have the problem of being hard to look up and prefixing them > with ~ feels like the worst of both worlds. > > Regards, > - Chris > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > I suspect xdebug would work fine if you can't use the IDE to ctrl-click on the operator. I highly suspect you'd never even use them except in specific cases where it would feel natural to do so (such as the money example, a units library, a matrix mathematics library, or a real number field library). Robert Landers Software Engineer Utrecht NL -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
Am 18.10.2023 um 18:42 schrieb Larry Garfield : > So the real question is: Would anyone who voted No on operator overloading > before vote Yes on it if it used ~=, ~>, ~+, etc. instead? I confess that I'm not a fan of operator overloading for a language like PHP but introducing new operators on top of making them overloadable seems a bad idea. Operators have the problem of being hard to look up and prefixing them with ~ feels like the worst of both worlds. Regards, - Chris -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023, at 1:12 PM, Robert Landers wrote: > On Wed, Oct 18, 2023 at 2:51 PM 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 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 Honestly I'm still on team operator-override. *Most* major languages have operator overloading, and it doesn't seem to cause a problem. (According 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 the previous operator overloading RFC would vote Yes on an operator-overloading-but-only-with-an-opt-in-prefix RFC. If not, then it doesn't really 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 already have. So the real question is: Would anyone who voted No on operator overloading before vote Yes on it if it used ~=, ~>, ~+, etc. instead? ---Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
On Wed, Oct 18, 2023 at 2:51 PM 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 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Custom object equality
Le 18/10/2023 à 14:50, someniatko a écrit : Hi internals, 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? I'm not fond of operator overloading, I actually quite hate it, I like the expressiveness of an equals() method. I would very much prefer to have a set of standard interfaces such as Comparable { compareTo($other): int } or Equatable { equals($other): bool; } which the standard API and userland libraries could make use of. In all cases, I don't like the ~= choice because in my mind it literally translates to "is approximately/barely/maybe comparable to". By the way, please do not use abbreviations such as WDYT, I'm not a native english speaker and I don't know all abbreviations, I had to duckduckgo' it. Regards, -- Pierre -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
[PHP-DEV] Custom object equality
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