Re: [RFC] User Defined Operator Overloads (v0.6)
| From: | Andreas Hennings | Date: | Tue, 21 Dec 2021 13:47:36 +0000 |
| Subject: | Re: [RFC] User Defined Operator Overloads (v0.6) | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-116701@lists.php.net to get a copy of this message | ||
On Tue, 21 Dec 2021 at 02:57, Jordan LeDoux <jordan.ledoux@gmail.com> wrote:
>
>
>
> On Mon, Dec 20, 2021 at 4:43 PM Andreas Hennings <andreas@dqxtech.net> wrote:
>>
>> > The exact position of where that trade-off is 'worth it' is going to
>> > be different for different people. But one of the areas where PHP is
>> > 'losing ground' to Python is how Python is better at processing data
>> > with maths, and part of that is how even trivial things, such as
>> > complex numbers, are quite difficult to implement and/or use in
>> > userland PHP.
>>
>> Could be interesting to look for examples in Python.
>> I was not lucky so far, but there must be something..
>> ...
>> Btw it would be really interesting to find such a list of
>> recommendations for Python.
>> The reference you added,
>>
>> https://isocpp.org/wiki/faq/operator-overloading#op-ov-rules, is for
>> C++, which is less comparable to PHP than Python is.
>
>
> During my research phase of this RFC I was able to review many different takes on this from the
> Python space. Here is one example of a community discussion about it:
>
>
> https://stackoverflow.com/questions/1552260/rules-of-thumb-for-when-to-use-operator-overloading-in-python
>
> One of the interesting things here is that *most* of the warnings for Python users discussed at
> the link are actually *designed* to not be issues within this RFC. That's on purpose of course,
> I tried to think about how some of the design issues in Python could be improved.
Right.
Your RFC might be the best we can do in the current PHP world, and
better than what exists in some other languages.
The remaining concerns would apply to any operator overloading RFC in
current PHP, and would not be special to this one.
>
> In Python, the +, +=, and ++ operators are implemented independently. In this RFC, you may only
> overload the + operator, and then the VM handles the appropriate surrounding logic for the other
> operators. For instance, with ++$obj or $obj++, you want to return either a reference or a copy,
> depending on if it's a pre- or post-increment. In this RFC, the handling of when the ZVAL is
> returned is handled by the VM automatically, and a subordinate call to the opcode for + is made when
> appropriate. The reassignment += works similarly, with the ZVAL's being assigned automatically
> and a subordinate call. This vastly reduces the surface for inconsistency.
I see the "Implied Operators" section.
I assume this means that a new instance will be created, and stored on
the same variable, _if_ the original operator is written in an
immutable way (which it should be)?
E.g.
$money = new Money(5);
$orig = $money;
$m2 = $money + new Money(2);
assert($money === $orig); // Checking object identity.
assert($m2 !== $orig);
$money += new Money(1); // Equivalent to $money = $money + new Money(1);
assert($money !== $orig);
assert($orig->amount() === 5);
I think we need a strong recommendation to implement operators as immutable..
>
> Another warning that is discussed is around overloading the == operator. A big reason for this
> is that the Python overloads do NOT require the == overload to return a particular type. Because of
> this, overloading the == operator can result in situations in Python where it is difficult to
> compare objects for equality. However, in this RFC the == operator can only be overloaded to return
> a boolean, so the semantic meaning of the operator remains the same. Though you could of course do
> something terrible and mutate the object during an equality comparison, you must return a boolean
> value, ensuring that the operator cannot be co-opted for other purposes easily. Additionally, the !=
> and == cannot be independently implemented in this RFC, but can in Python.
>
> In Python the inequality operators can be implemented independently: >, >=, <=, <.
> They *also* are not required to return a boolean value. In this RFC, independent overloads for the
> different comparisons are not provided. Instead, you must implement the <=> operator and
> return an int. Further, the int value you return is normalized to -1, 0, 1 within the engine. This
> ensures that someone could not repurpose the > operator to pull something out of a queue, for
> instance. (They could still repurpose >> to do so, but since the shift left and shift right
> operators are not used in the context of boolean algebra often in PHP, that's far less
> dangerous.) A future scope that I plan on working on is actually having an Ordering enum that must
> be returned by the <=> overload instead, that even more explicitly defines what sorts of
> states can be returned from this overload.
>
> A lot of years of language design experience have been invested into operator overloading
> across various languages. I wanted to at least try to take advantage of all this experience when
> writing this RFC. It's why I say that PHP will end up with the most restrictive operator
> overloads of any language I'm aware of. There will still be pain points (returning union types
> is not an easy thing to eliminate without full compile time type resolution), but as far as buggy or
> problematic code, there's a lot about this RFC that works to prevent it.
>
> A determined programmer can still create problems, but I find this (personally) an uncompelling
> argument against the feature. There are *many* features in PHP that a determined programmer can
> create problems with. The __get, __set, __call, and __callStatic magic methods can actually allow
> you to overload the *assignment* operator for certain contexts. The __toString magic method can
> already be used to mutate the object through a simple concatenation. The ArrayAccess interface
> forces you to deal with the union of *all* types (mixed), even when that doesn't make sense.
> And these are just the PHP features that in some way already interact with operators and objects in
> special circumstances.
>
> Jordan