Hi Sara,

On Jan 2, 2016, at 21:14, Sara Golemon <poll...@php.net> wrote:
> 
> Patricio Tarantino has asked me to help him propose Operator
> Overloading in PHP 7.1 (based in part on my operator extension in
> PECL).  I think we can expose this to usespace as magic methods with
> very little overhead (the runtime check and dispatch is already there,
> after all).
> 
> I do think that the "Future Expansion" section bears following through
> with as well, but the basic set of methods already hooked for GMP
> would be a nice start.
> 
> https://wiki.php.net/rfc/operator-overloading
> 
> -Sara


While I don’t necessarily think adding operator overloading is a great idea, I 
think if it’s to be done, we could do better. I’d offer two suggestions:

1) rather than the list of magic function names, use the actual operators 
themselves
> function ^($value)

or
> function operator <<($value)


This way, new magic methods don’t have to be created in the event we created 
new operators later. (Unlikely, I know.)

To handle ambiguity between prefix/postfix/infix operators, you could use 
something like:
> function prefix -($value)

> function infix -($left, $right)
> function postfix ++($value)


This would also address an issue in the proposal as written: __add and __sub 
don’t handle the ambiguity of prefix + and - operators.

Bishop Bettini suggests:
> public function __overload(string $operator, object $rhs = null); // $rhs === 
> null iff op is unary


but you really need separate functions (or an additional parameter) to handle 
that case. You can’t only pass in null because then you can’t disambiguate 
between $foo - null and -$foo.


2) I think we should take a look at Swift’s operator definition mechanism. 
Besides just allowing for operator overloading, Swift also allows you to 
specify entirely custom operators. For example (from the Swift Programming 
Language book, Language Guide, Advanced Operators chapter):

> “New operators are declared at a global level using the operator keyword, and 
> are marked with the prefix, infix or postfix modifiers:
> 
>> prefix operator +++ {}
> 
> The example above defines a new prefix operator called +++. This operator 
> does not have an existing meaning in Swift, and so it is given its own custom 
> meaning below in the specific context of working with Vector2D instances. For 
> the purposes of this example, +++ is treated as a new “prefix doubling 
> incrementer” operator. It doubles the x and y values of a Vector2D instance, 
> by adding the vector to itself with the addition assignment operator defined 
> earlier:
> 
>> prefix func +++ (inout vector: Vector2D) -> Vector2D {
>>     vector += vector
>>     return vector
>> }”

> “The following example defines a new custom infix operator called +-, with 
> left associativity and a precedence of 140:”
> 
>> “infix operator +- { associativity left precedence 140 }
>> func +- (left: Vector2D, right: Vector2D) -> Vector2D {
>>     return Vector2D(x: left.x + right.x, y: left.y - right.y)
>> }”

Operators can be defined as prefix, infix, or postfix. Infix operators can 
specify associativity (left, right, or none (default)) and precedence. Swift 
limits the first character of an operator is limited to one from a set of 
typical operator symbols and a set of unicode characters, so you can’t create 
or overload operators using arbitrary ascii characters.

In PHP, we might imagine this example to look like:

> //in global scope
> operator infix +- associativity(left) precedence(140);
> function +-($left, $right) { … }

In Swift, operator definitions and overloads are done in on a global basis (and 
multiple definitions are resolved appropriately with Swift’s type system). This 
makes sense for Swift, but it would be more difficult for PHP, given PHP’s more 
flexible type system. I’m unclear what the best approach is to handle 
typehints, which in this case are more part of the operator functions logic 
name than just run-time limitations on parameters.

The major problem I see with this, besides the parser complexity it would 
entail, is that it would make static analysis that much harder, and you wind up 
with PHP code that can’t actually compile unless the operator definitions are 
loaded.

-John


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

Reply via email to