On Fri, May 6, 2022, at 5:16 PM, Jordan LeDoux wrote:
> Hello all,
>
> I took a while away after my operator overload RFC was declined. I've been
> mulling for the last few months how to move forward while respecting the
> concerns and feedback of those who abstained and those who voted against.
> But I feel like a separate discussion needs to happen first after
> considering many different approaches.

Speaking only for myself, of course...

> # There is Considerable Demand For Improved Control of Operators with
> Objects
>
> This doesn't apply to all operators. I have not seen any comments in the
> last few months of digging of people who are desperate for the pow operator
> ( ** ) for instance. However, many people who work with math in PHP have
> use for at least the arithmetic operators and I see this comment frequently.
>
> Totally separate from the math domain, I've seen many comments about the
> desire to control the comparison operators: >, >=, ==, <=, <, !=, <>. This
> is something that would have numerous applications outside of mathematics,
> and there's even been an RFC worked on (that was declined in 2018) by Rudi
> to implement just comparisons.

I would group object operators into 4 categories/levels.

1. Object-universal operators.  This would be support for operators that make 
sense in all domains.  Mainly this is the comparison operators but there may be 
others.
2. Arithmetic operators.  The 4 basic operations.  Maybe even just 3 (excluding 
division as it's a bit more complex than the others conceptually).
3. Full operator overloading: If an operator exists, a class can override it, 
on principle, even if there's no obvious common use case.
4. Custom overloading: User-space can define additional operators for specific 
objects.

Jordan's RFC was effectively level 3, with a syntax designed to be extensible 
to level 4 in the future if desired.  Naturally the line between these levels 
if a little bit fuzzy and there's some overlap.

> # Different Voters Have Different Concerns
>
> This is an issue that almost all RFC authors must deal with of course, but
> this particular subject suffers from it more severely than most. For
> instance, in some of the past proposals that were more limited than mine,
> there were comments that a full operator overloading solution should be
> provided instead of something halfway.
>
> However one of the comments I received more than once was that I should
> separate out the comparison operators into its own RFC, since those have
> applications outside the math domain.

See above regarding "levels" of support.

> # Is Math A Valid Use Case?
>
> One of the more shocking (to me personally) pieces of feedback that I
> received from more than one person is that math is not a valid use case in
> PHP. I am... unsure about what to think of this opinion. I guess I would
> like to discuss and find out if this is widely believed among voters.

PHP is today rarely used for heavy-math use cases.  It's mostly 
line-of-business applications, aka "over-engineered ways of concatenating 
strings out of a database."  Historically it's been too slow for that, which 
lead to no community around it, so no one did it, so no focused improvements in 
that area, so...  Infinite loop.  Python got most of that attention instead.

However, the JIT and FFI work have quite frankly very little use *other than* 
computation intensive (ie, math) use cases, and those were added without issue 
despite having APIs that are extremely crappy. :-)   So I don't understand the 
"math doesn't matter" argument either; if it doesn't matter, we wouldn't have 
needed JIT or FFI either.

I frankly think this is a red herring; it's a "I don't do heavy math work in 
PHP, so arguing that feature X makes PHP better for math carries no weight."  
It shouldn't be read as "PHP being good at complex computations is bad in 
itself."  (If anyone does actually believe that, I'd say speak up but I'd just 
tell you that you're wrong from the get-go, so maybe let's not pick that fight 
and leave it as a hypothetical. :-) )

> # Non-Breaking Engine Changes
>
> The way that equality and comparison evaluation is done in the engine makes
> it impossible for certain kinds of overloading to be done, even in
> extensions. This isn't because that was an intended restriction, I
> discussed this issue with CMB and provided a PR a few months ago to resolve
> this, however it has remained in limbo:
> https://github.com/php/php-src/pull/7973
>
> # Overall Vision
>
> I'm not sure at this point how voters think objects and operators should
> work together into the future. I'd like to see if anyone is willing to have
> high-level discussion about the ideas, instead of picking at the
> implementation or details of a particular RFC.
>
> Jordan

I am always down for high-level ideas discussions. :-P

As even the detractors noted, the previous RFC is probably the best design that 
could be done, given PHP's existing nature.  So aside from the `operator` 
syntax for semi-methods, I don't think there's much to discuss there.

Conceptually, it is mostly true that any operator overload is simply syntactic 
sugar for a method call, and thus there's nothing that operator overloading 
enables that you can't do otherwise in more "self-documenting" ways (ie, 
methods).  I think that was the main pushback, that overloading just adds less 
self-documenting syntactic sugar over stuff you can already do.

However, there are 2 holes in that argument.

One, the same is true of all operators on scalars, too.  At a conceptual, 
computer-science-y level, all operators are shorthands for function calls.  `5 
+ 3` is simply a shorthand for `add(int, int)` called with 5 and 3.  (In some 
languages, scalar operators are literally implemented as functions/methods.)  
The only reason some common functions get magical short-hand operator syntax is 
historical precedent.  A very common historical precedent, but still, there's 
nothing intrinsic in integer addition that makes it necessarily have a magic 
symbol shorthand for its function.  In a pure sense, all operators are optional 
syntactic sugar.  (Give or take language-specific optimization that could be 
designed any way you want it to.)

Two, it's not entirely true that operator overloading offers no new 
functionality.  PHP has a number of operations that rely on comparisons in 
particular that do not have any override mechanism.  For example, `in_array()` 
with weak comparison can kinda-sorta work on arrays of objects, but only using 
the native "are each of the properties ==" algorithm.  There is no way to 
override that to some other definition of equal, the way the usort() family of 
functions allows for custom user-space comparisons.  in_array() offers no 
equivalent.  So if you wanted to have a unique-list of objects (a set), you 
need to do an awful lot of manual work with custom object identity logic and 
avoiding all of PHP's built-in list handling features.  It's technically 
possible to do, but at this point it's disingenuous to call it simply 
"syntactic sugar."  What's missing is, effectively, an engine-hook for equality.

That argument is less persuasive for the higher-level operators, like 
arithmetic or pow or modulus, as I am not aware of any missing "engine hook" 
situations for those.

My recommendation would be to use the same syntax and model as before and just 
target object-universal operators, ie, comparisons.  (Level 1 from above.)  
That gets the syntax in place, and lets us flush out the engine hook weirdness. 
 If we could get that to pass, it would at least get people comfortable with 
the idea and concept.  The higher level parts could then be an easier sell in 
the future in a version or two once people have gotten more used to the idea.

On the topic of the specific syntax, the trade-offs of magic methods would be:

* The names tell you what it is for, not what it looks like.  This may or may 
not be a good thing.
* It doesn't extend nicely to level 4 if we ever decide to go there.  (Whether 
you consider this good or bad is subjective.)

For the `operator` syntax, it's the other way around:

* The name tells you what it looks like without restricting what you can use it 
for. This may or may not be a good thing.
* Extending to later levels is syntactically trivial, including to level 4 if 
we want.  (Again, whether that's a pro or a con is subjective.)

I don't know if that particular syntax choice was a deal breaker for anyone but 
Nikita, though.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to