> On Aug 7, 2021, at 10:28 AM, Larry Garfield <la...@garfieldtech.com> wrote: > > The downside is that 30 seconds after that, 15 other libraries would do the > same in subtly incompatible ways, and then both Laravel and Symfony would > release their own that are incompatible with each other, and it would just be > a total mess because you would have NFI what any given operator is going to > do. Then FIG would try to define a few to standardize the madness, would > take about 10-12 months to do so, but both Symfony and Laravel would go on > using their own instead because they're big enough that they can do that, and > we'll have a mess basically forever. That is what my crystal ball tells me > would happen. > > So while this approach appeals to me personally, I think in the long run it's > probably a bad idea. My understanding is that many people consider C++'s > adoption of this approach a mistake, although I'm not a C++ developer so > cannot speak from first hand experience.
I strongly echo Larry's concern here. While I tend to be one who wants more language features, not less, the availability of unconstrained operator overloading can beckon an inexperienced and/or undisciplined developer to add operators for many of the classes they implement, whether or not doing is actually applicable or a good idea. I am even concerned about constrained operator overloading for the same reason. Here [1][2] are a couple essays to argue against operator overloading. Ruby has operator overloading, and one of the distasteful aspects I found regarding in programming in Ruby was that everybody's Ruby code you looked at felt like I was written in a slightly different language. I would hate that to become the case with PHP, more than it already is. I am actually surprised that the last operator overload RFC came close to passing because adding it seems like it would open a Pandora's box and yet other proposals that are less Pandoric seem to be anathema on this list. That said, I am not unsympathetic to the fact that operator overloading may well have some extremely valid use-cases, just ones that I do not personally seem to need on a day-to-day basis when writing code. Operator overloading seems to me to be of more value to those who are essentially wanting to write DSLs (domain-specific languages.) If that is indeed the case, and there are some DSL like features I wish we could add to PHP that would generally be non-starters for non-DSL usage. I wonder if there is a way to limit to only DSL use-cases? I doubt there is, but I had to pose the question in case someone else can envision a way to do so. So my main questions are: 1.) What are use-cases where operator overloading would really be valuable? 2.) Would it possible that instead of adding operator overloading we could add classes that could be extended where PHP actually defines the operators for those classes? If we can do #2 we can really work through all the issues with commutativity, associativity, etc. and also implement all and only the operators that make sense for the use-case. > On Fri, Aug 6, 2021, at 3:18 PM, Scott Arciszewski wrote: >> My recommendation is to have a base interface for every operator that can >> be overloaded, so that these can be composed together. >> >> AddOverloadInterface { __overloadAdd(): self; } >> SubOverloadInterface { __overloadSub(): self; } >> MulOverloadInterface { __overloadMul(): self; } >> DivOverloadInterface { __overloadDiv(): self; } >> ModOverloadInterface { __overloadMod(): self; } >> LeftShiftOverloadInterface { __overloadLeftShift(): self; } >> RightShiftOverloadInterface { __overloadRightShift(): self; } >> XorOverloadInterface { __overloadXor(): self; } >> etc. > > That would be roughly how Stringable/__toString works now. I'd be OK with > that, if it's going to be a language trend. If this is how it turns out, I would hope for consistent naming, e.g. Addable vs. AddOverloadInterface, Subtractable vs. SubOverloadInterface, and so on. > On Aug 7, 2021, at 1:48 PM, Dan Ackroyd <dan...@basereality.com> wrote: > On Fri, 6 Aug 2021 at 21:18, Scott Arciszewski <sc...@paragonie.com> wrote: >> It's probably worth exploring whether common combinations are worth >> defining for convenience. > My understanding of the current consensus is "let's not". > > That's based from the discussion on whether defining 'number' as 'int > | float' would be worth doing, mostly because adding aliases don't > provide much value, While it may (or may not?) be consensus, I argue the counter which is that adding `number` to PHP to mean `int|float` would provide the value of: 1.) Standardization and 2.) interoperability between libraries that use `number`. This argument *assumes* there would be a strong consensus that `number` should actually mean `int|float` and not something else, or not some other name. For clarity I am not arguing that number *means* int|float — I'd have to review the debate and see if there was strong consensus — but instead that *if* there is strong consensus that the term `number` *does* unequivocally mean `int|float` then there is a value to adding `number` as an alias to PHP, again for 1.) standardization and 2.) interoperability. > and once you've started adding some, where do you > stop? e.g. if we defined 'number' why not also define 'scalar'? Yes, assuming there is strong consensus on what `scalar` should mean. I would use the same argument as above to support adding `scalar` as a standardized union type. > The value for interfaces is even lower than other types, as it's > already possible in userland to define your own combination types: > > interface MatrixMath extends __AddInterface, __AddSubInterface, > __AddMulInterface {} > > as interfaces can extend multiple other interfaces at once. > On Aug 7, 2021, at 6:28 PM, Larry Garfield <la...@garfieldtech.com> wrote: > > I would argue that the micro-interface approach has a far better success rate > in PHP, especially when it comes to "magic" behavior/engine hooks. If we're > going to adopt operator overloading, that is the safest middle-ground to take. I think this it yet another argument for implicitly-implemented interfaces as I mentioned last week[3]. Agreed, micro-interfaces are definitely a better approach, but having to explicitly mention them limits their defacto-standardization and thus adoption. One reason is two libraries are unlikely to both use a 3rd party interface that forces a dependency, and thus they will often create two potentially-conflicting interfaces. So the implementor of their interfaces can often only implement an interface from one or the other library, but not both and users of that interface has to choose which one to accept in their variables and parameters as well as which one to return with their functions and methods. OTOH, two differently named implicitly-implemented interfaces are compatible if both have the same signature. A function that accepts as a parameter an instance of a class from one library that implicitly implements its own interface can accept an instance of a class from the other library that implicitly implements its other identically-signatured interface. Thus interoperability is improved, defacto-standardization is more likely to occur and serendipity is born, as has been shown to be true in the Go ecosystem. Implicitly-implemented interfaces give us a better way. The library vendors after the first could write classes that are compatible with the original libraries, even if they are competitors, without having to force an external dependency on a (possibly competitive) library. Laravel and Symphony would be more likely to see eye-to-eye on at least a few of their interfaces even though their overall philosophies are so drastically different. > Conversely, if you want to accept an object that is addable, subtractable, > and comparable, you can type it exactly like that: > > function foo(Addable&Subtractable&Comparabie $var) {} That really begs for userland-definable types, e.g.: Additive[4] type Additive = Addable&Subtractable&Comparabie function foo(Additive $var) {} That's been discussed many times before but AFAIK is not moving forward by anyone. (I would propose, but with so many RFCs that I would like to propose I would not know how to implement.) Is there some prerequisite we need to achieve before we can pursue that? > To be fair, this approach would not prevent weirdos like me from implementing > __add() and using it as a Monadic bind operator or something silly like that. > However, I believe experience has shown that a combined Arithmetic interface > wouldn't stop me from doing silly things either, given experience with > ArrayAccess. Agreed. That is why (IMO) (almost?) all interfaces added to PHP should either be individual, or an aggregate of other interfaces. If ArrayAccess where simply the aggregate of these interfaces PHP developers would be in a better position: interface OffsetExists {...} interface OffsetGettable {...} interface OffsetSettable {...} interface OffsetUnsettable {...} -Mike [1] https://cafe.elharo.com/programming/operator-overloading-considered-harmful/ [2] https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/ [3] https://externals.io/message/115554#115603 [4] https://english.stackexchange.com/a/170247/1164 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php