Hi Jan,
On 28/01/2020 23:14, jan.h.boeh...@gmx.de 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]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php