Re: Operator overloading for userspace objects
| From: | Mike Schinkel | Date: | Fri, 31 Jan 2020 17:32:06 +0000 |
| Subject: | Re: Operator overloading for userspace objects | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-108337@lists.php.net to get a copy of this message | ||
> 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