Hi Johannes,

Thank you for your points! I think you point out some overlooked issues.

Johannes Schlüter wrote:
Which one is being called? - Vector's or Matrix's.  How will your
vector know about my Matrix?

The way C++ solves this is by allowing non-member functions as
operators.

      #include "vector3.h" // provides class Vector3
      #include "matrix.h"  // provides class Matrix, potentially
                           //  from a different vendor

      Matrix operator*(const Vector3 &lhs, const Matrix &rhs) {
          // I can provide  this myself if neither Vctor's nor
          // Matrix's vendor do
          return ...;
      }

      int main() {
          Vector3 vec{...};
          Matrix matrix{....};

           // works
           auto result = vec * matrix;
      }

I wonder if it would be a good idea, if we do want operator overloading in PHP, to implement a similar mechanism for this. Perhaps type-specific overloads could be registered via some special function call or declaration, something vaguely like:

  class Vector {
    public function __construct() {
      php\register_overload($this, Matrix::class, '*', function ($a, $b) {
        /* multiplication implementation here */
      });
    }
  }

The engine could then do type-matching for you, and would implement commutativity for you if the operator is commutative, so `$someVector * $someMatrix` would call the above function, but so would `$someMatrix * $someVector`. (Note: to support matrix multiplication, I guess commutativity must be overridable. Also, I have forgotten whether multiplying a matrix and a vector is commutative or not :p)

I think this approach would be less messy than having to implement full type matching on both sides of a type pair, for a number of reasons:

* Instead of Vector having to have an implementation of __mul which checks for Matrix, and Matrix having to have an implementation of __mul which checks for Vector, just one of these types can call register_overload with a single implementation (because the operation is commutative). * Whether two types can be used with a particular operator is clear: either there is such a pair registered, or there is not, and PHP can give appropriate error messages. It is unlikely there will be an issue where one side has __mul but it just throws an exception or somethig. Also, in a case like `$a * $b`, $a can implement support for $b without $b having to support $a, while at the same time $b can implement support for some unrelated other type, without `$b * $a` not working (with the current proposal, imagine $a's __mul handler supporting $b but not vice-versa). * The engine can see conflicts (one class declares an overload involving the other class, and vice-versa) and warn about them, rather than `$a * $b` silently having completely different behaviour to `$b * $a`.

This is not to say we necessarily should implement this, but it may be worth thinking about…

Thanks,
Andrea

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

Reply via email to