>
>
> On Mon, 2020-03-23 at 18:58 +0100, jan.h.boeh...@gmx.de wrote:
> > Hi internals,
> >
> > I have opened voting on
> > https://wiki.php.net/rfc/userspace_operator_overloading, which allows
> > users to overload operators in their own classes.
> >
>
> I consider operator overlaoding in general a good feature (while PHP's
> overload for + on arrays is weird)
>
> However I don't like this design.
>
> Consider this case: Some library provides a type A without overloads. I
> then create a type B with overload:
>
>     class B {
>         static public __add($lhs, $rhs) {
>             if ($lhs instanceof A) ...
>             elseif($rhs instanceof A) ...
>             else error
>         }
>     }
>
> as I want my type's addition to commutative I handle this with some if
> (probably dispatching. Now I can invoke it:
>
>    new A() + new B(); // calls B::__add()
>    new B() + new A(); // calls B::__add() as well
>
> Now the maintainer of A implements the feature request "A should allow
> addition with integers", I update my library and suddenly weird things
> happen.
>
>    new A() + new B(); // calls A::__add() and explodes, as A doesn't know
> B
>    new B() + new A(); // calls B::__add() works as before
>
> Now we could establish the best practice that one type's operator calls
> the other type's operator in case it can't handle a type. However that
> is no good option as it will lead to infinite recursion if neither type
> can handle both operands.
>
>
> The issue is that by forcing type declarations as part of the class, as
> members, this forms a closed set, but for many cases a strict closed
> set isn't what one wants. For mathematical types having operators
> working with integers (and other numeric values) is essential.
> Communativity often also is required.  So a true closed set doesn't
> work, for an open set can't be created easily in today's PHP. Thus the
> RFC tries to tie this together, but this will fall apart and then cause
> legacy and BC reasons preventing future improvement.
>
> I believe the pre-requisit is having some form of function overloading,
> where operator functions for specific argument types can be defined. In
> https://news-web.php.net/php.internals/108425 Andrea created an idea,
> which is probably "ugly" but has less usage restrictions. I think
> spending time on function overloading (I believe, without proving it,
> this can be done with very little cost for non-overlaoded cases - by
> adding a flag "overloaded" along visibility flags and check that along
> with the visibility check, only in case of an overload to the
> "expensive" check, which still is cheaper done in the engine than
> if/else chains in userspace) and then take up operator overloading
> again, rather than this smart but limited approach. (For whoever does
> that: spend time in C++ and its function resolution rules incl. ADL,
> not to copy, but to learn)
>
> johannes
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
This issues become even more apparent when sequencing operations like `$a +
$b + $c - $d`. Trying left, then trying right, will make it very difficult
to determine the outcome of such a statement.

The arguments against type hinting for operator methods, assume the "try
left/right" method. Instead, type hinting should be applied to determine
which method should be used. If both or neither methods are applicable, an
error must be thrown.

With class inheritance, you also don't want to rely on the order of the
operands. If you're the creator of a library, that's out of your hands. If
both the parent and child class overwrite the operation, and both accept
the operands, then the child class should always be used.

It's a -1 for me. I would vote in favor of an RFC for operator overloading
without the "try left, try right" behavior.

Arnold

Reply via email to