Re: [PHP-DEV] Operator overloading for userspace objects

This is only part of a thread. view whole thread
  108337
January 31, 2020 17:32 mike@newclarity.net (Mike Schinkel)
> On Jan 31, 2020, at 10:41 AM, Larry Garfield <larry@garfieldtech.com> wrote: > > I cannot speak to the implementation details. From a design perspective, I am tentatively positive on operator overloading, with separate method for each operator, BUT, the big question for me is the rules around type compatibility.
I have avoided commenting on this thread to see where it would lead. I have been surprised so many here are embracing operator overloading. My experience taught me operator overloading has been added to languages because "it seemed like a good idea at the time." But it is now considered to be harmful, by many: - https://www.quora.com/What-are-the-pitfalls-of-operator-overloading - https://cafe.elharo.com/programming/operator-overloading-considered-harmful/ - https://www.oreilly.com/library/view/sams-teach-yourself/0672324253/0672324253_ch21lev1sec4.html - https://en.wikipedia.org/wiki/Operator_overloading#Criticisms - https://www.jarchitect.com/QACenter/index.php?qa=53&qa_1=overload-operators-special-circumstances-defined-literals (Ruby's ability for developers to redefine the entire language is an especially chilling example of the concepts of operator overloading taken to the extreme: https://dev.to/jimsy/please-stop-using-ruby-4lf1) That said, I will not protest further if others still really feel strongly about adding operator overloading after reviewing those criticisms.
> Also, I want to reiterate: Any of these operations MUST be designed to return a new value, never modify in place. These operators only make sense on value objects, not service objects, and value objects should be immutable. > > Which means that there is no __addEquals() method, just _add(), and we continue with that being isomorphic to $a = $a + $b;, the behavior of which is readily predictable.
Immutability is a great feature from functional programming. But I think it is orthogonal to operator overloading as it would be (relatively) easy to implement an __add() method but how would PHP enforce that __add() would not be able to mutate state? Consider the following. How would __add() stop the mutating happening in $foo->bar->increment_ops()? class Bar { private $_op_count = 0; function increment_ops() { $this->_op_count++; } } class Foo { public $value; public $bar; function __construct( int $value ) { $this->value = $value; } function __add( Foo $foo ): Foo { $this->bar->increment_ops(); return new Foo( $this->value + $foo->value ); } } $foo = new Foo(10); $foo->bar = new Bar(); $foo = $foo + new Foo(5); echo $foo->value; I am sure it would be _possible_ to stop it, but I do not think it is trivial to architect nor implement. Given that I believe immutability would need to be implemented as an independent feature and not as an aspect of operator overloading. If we still want operator overloading and we want to force operator overloading to require immutability, I believe that means we would need an immutability RFC to be approved (and implemented?) before operator overloading requiring immutability could be approved. Something like this: class Bar { private $_op_count = 0; immutable function increment_ops() { global $foo; $foo = new Foo(); <====== Compile error! $this->_op_count++; <====== Compile error! } }
> I've actually been wondering lately if we shouldn't create an entirely separate data structure for value objects...
+1 for that. -Mike
  108338
January 31, 2020 18:35 ben@benramsey.com (Ben Ramsey)
> If we still want operator overloading and we want to force operator overloading to require immutability, I believe that means we would need an immutability RFC to be approved (and implemented?) before operator overloading requiring immutability could be approved. Something like this:
For reference, immutability has been proposed in the past, but I’m not sure where it landed. It looks like it fizzled out. * https://wiki.php.net/rfc/immutability * https://externals.io/message/94913 * https://externals.io/message/96919 * https://externals.io/message/97355 * https://externals.io/message/101890 * https://externals.io/message/81426 I agree with you that I think we need to accept an immutability RFC before operator overloading (requiring immutability) can be approved. I also believe operator overloading should require immutability. Cheers, Ben
  108340
February 1, 2020 00:03 larry@garfieldtech.com ("Larry Garfield")
On Fri, Jan 31, 2020, at 11:32 AM, Mike Schinkel wrote:
> > On Jan 31, 2020, at 10:41 AM, Larry Garfield <larry@garfieldtech.com> wrote: > > > > I cannot speak to the implementation details. From a design perspective, I am tentatively positive on operator overloading, with separate method for each operator, BUT, the big question for me is the rules around type compatibility. > > I have avoided commenting on this thread to see where it would lead. > I have been surprised so many here are embracing operator overloading. > > My experience taught me operator overloading has been added to > languages because "it seemed like a good idea at the time." But it is > now considered to be harmful, by many: > > - https://www.quora.com/What-are-the-pitfalls-of-operator-overloading > - > https://cafe.elharo.com/programming/operator-overloading-considered-harmful/ > - > https://www.oreilly.com/library/view/sams-teach-yourself/0672324253/0672324253_ch21lev1sec4.html > - https://en.wikipedia.org/wiki/Operator_overloading#Criticisms > - > https://www.jarchitect.com/QACenter/index.php?qa=53&qa_1=overload-operators-special-circumstances-defined-literals > > (Ruby's ability for developers to redefine the entire language is an > especially chilling example of the concepts of operator overloading > taken to the extreme: https://dev.to/jimsy/please-stop-using-ruby-4lf1) > > That said, I will not protest further if others still really feel > strongly about adding operator overloading after reviewing those > criticisms.
Those are valid points. (Hence my "tentatively.") Operator overloading is one of those features that when used well can be really really nice, but is really easy to use badly (in which case it's really really not nice). In all honesty, I'd probably be more excited about bringing back comparison overloading (__compare() and __equals()) than overriding arithmetic. Unless we could get some kind of bind operator, but that's probably asking for trouble. :-)
> > Also, I want to reiterate: Any of these operations MUST be designed to return a new value, never modify in place. These operators only make sense on value objects, not service objects, and value objects should be immutable. > > > > Which means that there is no __addEquals() method, just _add(), and we continue with that being isomorphic to $a = $a + $b;, the behavior of which is readily predictable. > > Immutability is a great feature from functional programming. But I > think it is orthogonal to operator overloading as it would be > (relatively) easy to implement an __add() method but how would PHP > enforce that __add() would not be able to mutate state?
Currently it cannot. That's another point of concern. We could at best document it and put "please please don't modify the object" in the docs, but that would probably work just as well as you think it would... All of this is pointing in the "we need a language construct for value objects" direction, which I believe would be highly useful but I don't know how we'd do it nicely. (Mainly, how to handle what PSR-7 does with withX() type methods, which are clunky but the best we can do without some really funky new syntax.) --Larry Garfield