Re: [PHP-DEV] Operator overloading for userspace objects

This is only part of a thread. view whole thread
February 2, 2020 14:29 (Rowan Tommins)
Hi Jan,

On 28/01/2020 23:14, wrote:
> the last days I have experimented a bit with operator overloading in > userspace classes (redefing the meaning of arithmetic operations like +, -, > *, etc. for your own classes).
Thanks for bringing this up, and starting to dig into the implementation details. I think there are two different philosophies of what operator overloading is for, which lead to different design decisions, so I think we should be clear which one we're embracing. - The ability to define new types that mimic the behaviour of basic types, e.g. making arbitrary-precision number objects behave just like built-in floats and ints. - The ability to attach an operator to any type with a domain-specific meaning, like a method with a funny-looking name, e.g. using . to represent "dot-product" within a matrix arithmetic library, rather than tying it to the meaning "concatenation". If you think of operator overloading as mimicking existing types, some possible implications: - Justifying every overload offered with an explicit use case - Overloading named operations, not operator symbols - e.g. "__add" rather than "operator+" - Requiring operations to be grouped - e.g. "type classes", where you can't just implement "add", you have to implement everything needed to "behave as a number"; in PHP terms, an interface rather than independent magic methods - Deriving additional operations from those implemented - e.g. defining "compareTo" is enough to implement < <= == != >= and >; or implementing "add" is enough to derive multiplication by an integer ($a * 3 => $a + $a + $a) and even exponentiation ($a ** 3 = $a * $a * $a) If you think of operator overloading as a tool for domain-specific language design, the implications are rather different: - Treating the symbol as the important thing, not its traditional meaning - e.g. "operator+" rather than "__add" - Only restricting operators from overloading where there is some over-riding reason, e.g. reserving the meaning of === but allowing ~ regardless of whether "bit-wise operations" have any particular use case - Allowing the user to create entirely new operators, with their own meanings; Postgres, for instance, defines an operator as a sequence of 1 to 63 of the characters + - * / < > = ~ ! @ # % ^ & | ` ? with a few technical restrictions; Raku/Perl6 allows pretty much any Unicode character - Allowing every operator to be implemented separately, with whatever result is desired; if . can mean "dot product", there's no reason <= couldn't mean "derive from" - Not assuming any relationship between operators once they've been overloaded; so implement <=> doesn't imply availability of < and > unless the user has opted into that relationship (e.g. using a Trait to import a definition for additional overloads) Regards, -- Rowan Tommins (né Collins) [IMSoP]