> On Aug 9, 2021, at 8:40 PM, Jordan LeDoux <jordan.led...@gmail.com> wrote: > That is in part of why I asked for use-case examples, to see if there really > were a lot of use-cases where operator overloading makes sense. You only > provided two categories; Math and the already existing DateInterval. > > This seems... a bit reductionist? I suppose if you consider anything that has > a numeric value "math", then sure.
I can see how you might have interpreted my reference to Math as "all math." However, I was only referring to the explicit list you provided. Again, for reference: Math ------------ - Complex number objects - Fractions objects - Matrix objects (math) - Vector objects (math) - Arbitrary precision numbers (which are usually represented as a string in PHP) > Math is extremely large. Geometry is very different from matrices, which is > very different from arithmetic, which is very different from complex numbers. So that gives me two (2) thoughts 1.) First is Geometry would be another area for PHP to consider adding classes. 2.) Then I thought: What if PHP had the ability to explicitly define *value* objects? I know this has been something Larry Garfield has mentioned[1] in the past. What if we had a new type of class that is to be used only for value objects. Following Larry's lead they would be immutable. And if we had those then I think adding generic operators overloading to value objects would make a hell of a lot of sense. Maybe: #[\PHP\Value] class ComplexNumber{} Or: class ComplexNumber value{} Or: ??? Can you see any reason why only allowing the addition of operator overloads to *value* objects would too limiting? IMO that would minimize the abuse potential for implementing operators as a leaky abstraction when developers are ignorant of the ramifications and/or are more concerning about their convenience than longer term maintainability. [1] https://twitter.com/Crell/status/621715583403487232 > Again, I'm providing those examples because I can literally bring up code > from my own libraries for those, so I'm a good advocate for them. But others > certainly exist. I think you would throw this under "math", but what about > unit-based values? If you wanted to do `19cm + 2m`, you could return `219cm`, > or `2.19m`, or `2190mm`. Supposing that there was an abstract, how would it > know what unit conversion to use? Or what about `2km + 4mi`? Or what about > erroring for `2km + 4L`? Length is a really great example, thanks for bringing it up. According to NIST there are seven (7) base units[2] where "Definitions of all seven (7) SI base units are expressed using an explicit-constant formulation and experimentally realized using a specific mises en pratique (practical technique)." This means they are well-known and unlikely have changing requirements. They are: • Length e.g. meters • Time e.g. seconds • Amount of substance e.g. moles • Electric current e.g. amperes • Temperature e.g. kelvin • Luminous intensity e.g. candela • Mass e.g. kilogram Those seem like a great *finite* list of fundamental units I would argue PHP could benefit userland developers greatly by adding *standardized* classes to handle them, maybe in a `PHP\Units` namespace. We already have Time. Then I can envision a `Value` base class, trait(s) and/or interfaces that could support generic unit conversion that these specific units, like Length. 1 'm' could be defined equal to 100 'cm' and then this could be possible: use PHP\Units\Length; $length = (new Length(19,'cm')) + (new Length(2,'m')); echo $length->toCentimeters(); // prints 219 echo $length->toMeters(); // prints 2.19 echo $length->toMillimeters(); // prints 2190 $length = (new Length(2,'km')) + (new Length(4,'mi')); echo $length->toMiles(); // prints 5.24274 echo $length->toKilometers(); // prints 8.43736 Then something like this could also be valid, and be what the above is actually built on: use PHP\Units\Units; use PHP\Units\Value; $units = new Units(); $units->addUnit('m','Meter'); $units->addUnit('cm','Centimeter'); $units->addUnit('mm', 'Millimeters'); $units->addConversion('cm','m',100); $units->addConversion('mm','m',1000); $length = (new Value(19,'cm',$units)) + (new Value(2,'m',$units)); echo $length->toUnit('cm'); // prints 219 echo $length->toUnit('m'); // prints 2.19 echo $length->toUnit('mm'); // prints 2190 $units->addConversion('m','km',1000); $units->addConversion('mi','km',1.60934); $units->addUnit('km', 'Kilometers'); $units->addUnit('mi','Miles'); $length = (new Length(2,'km',$units)) + (new Length(4,'mi',$units)); echo $length->toUnit('km'); // prints 5.24274 echo $length->toUnit('mi'); // prints 8.43736 We could even open up the discussion of having scalar literals for these types, e.g. where `2m` is a 2 meter value object of type Length. Note that having value objects and having these seven units of measure added to PHP need not be mutually exclusive. As an aside, if you take 10 developers and ask them to create a ComplexNumber class you will almost certainly get 10 different, unique implementations. However, if a ComplexNumber class is added to a language there is a good chance all 10 developers would just use it and not rebel against it. That is not always the case — look at the SPL — but while most people may grumble about the string functions they all still use them. And same for the DateTime and DateInterval classes. I expect the same would be true for a Length class, et.al. [2] https://www.nist.gov/pml/weights-and-measures/metric-si/si-units > Another good example of unit based values would be online stores controlling > inventory and carts. You could have item ID's be the 'unit' to control them, > or perhaps you 'unit' them by their shipping size. Or perhaps store items > actually have several units attached to them, so that you could automatically > combine shipping volumes and weights, while in other locations combining > quantities and prices. And that IMO is an example where operator overloading could end up being a leaky abstraction where different developers would have different conceptions for what each unit should be. > All of these things are *possible* in PHP. This doesn't enable those things. > But it makes them cleaner and easier to reason about, and reduces the code > necessary to accomplish them. I'd argue for the shopping cart example it would make it more difficult to reason about for the very reason that you gave three different potentials for how to define a unit. As for Length being appropriate for operator overloading, absolutely. > Yet Go is essentially built around routines and concurrency which is an > incredibly complicated feature. I think that there is certainly complexity in > operator overloads, but I feel (and will attempt to demonstrate with this > RFC) that the benefits are worth the complexity. As someone whose two languages are PHP and Go I am not sure Go is "essentially built around routines and concurrency." I find Go to be much more than that. However, that debate is a digression from our topic so we shouldn't further it here. > Well, the first answer would be that I use PHP for my day job. I also use > Python, but much more sparingly. Python can accomplish all the things that I > want to do... I mean NumPy and SciPy exist and cover virtually every math > case that has even been hinted at so far in this thread. But PHP is the > language I enjoy the most. That at its core is why I started writing a math > library for PHP years ago. I like the language, and I want it to be better, > and I wanted to contribute something to help people accomplish goals that > were difficult to accomplish in the language. That's still my motivation now, > and that's one of the things I hope to achieve with this RFC. Fair point. > R and Haskell are also very capable math languages, yet all three languages > are used. I don't think the idea that another language has better tools for a > particular task is an argument against making PHP more capable at that task. True. Unless adding those tools make it less capable at the tasks its best for. And I am arguing that adding generic operator overloads for all classes may well make PHP less capable for those who want to write robust and reliable web applications. (If we add value object classes and add generic operator overloads there, I feel much less concerned about PHP becoming less capable of achieving robustness and reliability.) > They are deterministic for given *values* and *types*. They are not > deterministic over the whole category. I think that may be a distinction without a difference. > However your suggestion is an excellent one. I will add some interfaces and > abstract classes to that repository when I am able to illustrate what user > implementations (or the PHP expressions of the C implementations) might look > like. AWESOME! > The overloaded operators don't interfere with anything *at all* unless you > use an object that has them defined, even if you use the extensions. The GMP > operator overloads don't affect anyone unless they are using GMP. These will > be the same, in that the operators are unaffected unless a class opts in to > using the feature. Yeah. I don't think I was saying those overloaded operators affect anything else. I was suggesting that approach as a potential model. One final question. Let's assume that the functionality in your library were to be added to PHP such that your library was no longer needed. Would you be fine with that, or do would you prefer that features added to PHP made your library more attractive as opposed to no longer needed? I'm not suggesting anything untoward — it would be perfectly reasonable IMO for you wanting features to enhance your library vs. eliminate the need for it — I am just interested to know which avenue you would find most compelling? -Mike P.S. I've seen when language features are added that eliminate the need for selected domain-specific libraries it can actually give the library author room to provide even more specific functionality and increase the library's value and thus increase the library's adoption, rather than killing it. #fwiw -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php