On Tue, 21 Dec 2021 at 00:03, Dan Ackroyd <dan...@basereality.com> wrote: > > On Fri, 17 Dec 2021 at 18:36, Stanislav Malyshev <smalys...@gmail.com> wrote: > > > > When reading > > this code: $foo * $bar - how do I know which of the ways you took and > > where should I look for the code that is responsible for it? When I see > > $foo->times($bar) it's clear who's in charge and where I find the code. > > Terse code is nice but not at the expense of making it write-only. > > Well, there's only two places to look with operator overloads, but > yes you're right, using operator overloads for single operation is not > a good example of how they make code easier to read. The more > complicated example from the introduction to the RFC > https://wiki.php.net/rfc/user_defined_operator_overloads#introduction > shows how they make complex maths easier to read.
I think the example in the RFC is interesting, but not ideal to advertise the RFC. The example is with native scalar types and build-in operator implementations. (I don't know how GMP works internally, but for an average user of PHP it does not make sense to call this "overloaded") In fact, if we add overloaded operators as in the RFC, the example becomes less easy to read, because now we can no longer be sure by just looking at the snippet: - Are those variables scalar values, or objects? - Are the operators using the built-in implementation or some custom overloaded implementation? (depends on the operand types) - Are the return values or intermediate values scalars or objects? We need really good variable names, and/or other contextual information, to answer those questions. This said, I am sure we _can_ find good examples. In this thread, people already mentioned Matrix/Vector, Money/Currency and Time/Duration. Others would be various numbers with physical measuring units. > > The exact position of where that trade-off is 'worth it' is going to > be different for different people. But one of the areas where PHP is > 'losing ground' to Python is how Python is better at processing data > with maths, and part of that is how even trivial things, such as > complex numbers, are quite difficult to implement and/or use in > userland PHP. Could be interesting to look for examples in Python. I was not lucky so far, but there must be something.. > > Stanislav Malyshev wrote: > > And again, what's the intuitive > > difference between operators +=+@-+ and ++--=!* ? > > That's not part of the RFC. > > There's enough trade-offs to discuss already; people don't need to > imagine more that aren't part of what is being proposed. > > > I have encountered > > toolkits where the authors think it's cute to define "+" to mean > > something that has nothing to do with mathematical addition > > Rather than leaving everyone to make the same mistakes again, this RFC > might be improved by having a list of stuff that it really shouldn't > be used for. At least then anyone who violates those guidelines does > so at their own risk. Having guidelines would also help junior devs > point out to more senior devs that "you're trying to be clever and the > whole team is going to regret this". > > I started a 'Guidelines for operator overloads' here > (https://github.com/Danack/GuidelinesForOperatorOverloads/blob/main/guidelines.md) > - if anyone has horrorible examples they'd like to add, PR's are > welcome. I think it is a good start. I would avoid appealing to "common sense" or "logical sense" though, this can mean different things to different people, and is also somewhat tautological, like "do good things, avoid bad things". More meaningful terms can be "familiar", "expectations", "predictable", "non-ambiguous". (I see this language is coming from the C++ document, but either way I don't like it) Possible alternative language snippets: For designing operators: - Replicate familiar notations from the subject domain, e.g. maths, physics, commerce. (this has some overlap with the first point) - Return the type and value that people expect based on their expectations and mental models. - Use identifiers (class names, method names, variable names) from the same subject domain language that inspires the operators. - Avoid ambiguity: If different people will have different expectations for return type and value, introduce well-named methods instead of overloaded operators. - Completeness trade-off: Understand the full range of operators, and type combinations for the same operator, that is common in the subject domain. Then decide which of those should be supported with operator overloads, and which should be supported with methods instead. - Take inspiration from code examples outside of PHP. For using operators: Use descriptive variable names, method names, other identifiers, and other hints (@var comments etc), so that the type and role of each variable and value can be easily understood. E.g. "$duration = $tStart - $tEnd;". "If you provide constructive operators, they should not change their operands." I think we should use the term "immutable": Operators should be immutable to the operands. If operands are objects, the operator should return a new instance instead of modifying the existing instance. For +=, we should still recommend immutable behavior. It is just so much better :) $price = new PriceInDollar(5); assert($price->amount() === 5); $old_price = $price; assert($price === $old_price); // same object. $price *= 2; // Shortcut for "$price = $price * 2;", creating a new instance. assert($price->amount() === 10); assert($old_price->amount() === 5); assert($price !== $old_price); // different object. ---------- Btw it would be really interesting to find such a list of recommendations for Python. The reference you added, https://isocpp.org/wiki/faq/operator-overloading#op-ov-rules, is for C++, which is less comparable to PHP than Python is. -- Andreas > > cheers > Dan > Ack > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php