5 ms·
I never understand the hate operator overloading gets. Why is it collectively decided that date.plus(1, ChronoUnit.DAYS) is 100% fine and dandy, but date + Chro
by dtech 5y ago
I never understand the hate operator overloading gets. Why is it collectively decided that date.plus(1, ChronoUnit.DAYS) is 100% fine and dandy, but date + ChronoUnit.day(1) would be like introducing longjmp.
- Koshkin 5y agoNot to mention that operator (and function) overloading is absolutely unavoidable when you are dealing with generics. A generic type may itself define an operator, which, of course, becomes overloaded due to its origin, or such a type may require that an operator on another, parameter type, exists and satisfies certain “axioms” (such as associativity).
- oweiler 5y agoMost devs probably know operator overloading from C++ and Scala, which both go way overboard with them. Operator overloading on a limited set on operators, like in Kotlin is fine.
- seanmcdirmid 5y agoC#’s limits are much more reasonable than Kotlin’s. The former allows overloading comparison operators with return values other than Booleans (eg if you want to return wrapped Boolean types), the latter does not (so Kotlin EDSLs rely on eq, lt style infix operators). C# on the other hand doesn’t (or didn’t?) allow for operators to be defined via extension-type overloading. Not that limitations are bad, Kotlin is just weird in them.
- matheusmoreira 5y agoI don't understand it either. It's just yet another Java limitation that better languages simply don't have and which must be constantly worked around. There's no reason why we can't have a method named + which adds the receiver to the argument. It's just a simple symbol. x + y x.+(y) The root cause of this is the distinction between primitive and object types. Simply put, not everything is an object in Java and this causes numberless problems. One of them is the need for special syntax cases for the mathematical operators of the primitive types.
- dtech 5y agoThis is exactly how scala does it
- matheusmoreira 5y agoYeah. It's also how Ruby and Smalltalk do it. Lisp also does similar things. In these languages it doesn't even make sense to talk about operators. They don't exist. There are only methods, functions. General ideas represented by a few universal concepts. No special cases. Of course they can be overridden... It would have been strange if they couldn't. They're just normal methods or functions.
- igouy 5y agoNo special cases; apart from the special cases ;-) Some Smalltalk methods are "compiled in-line" special — ifTrue: alternativeBlock "If the receiver is false (i.e., the condition is false), then the value is the false alternative, which is nil. Otherwise answer the result of evaluating the argument, alternativeBlock. Create an error notification if the receiver is nonBoolean. Execution does not actually reach here because the expression is compiled in-line." self subclassResponsibility
- matheusmoreira 5y agoThat's just the implementation though, isn't it? In the language proper, the method still exists. The implementation just compiles it away.
- igouy 5y agoHow would — "Of course they can be overridden..." — work when the method is: ifTrue:
- ModernMech 5y agoOperator overloading is great for library authors, bad for basically everyone else. What operator overloading buys you is fewer keystrokes to express a concept. For someone intimately familiar with a codebase, like a library author, this is awesome. It is a great save if you can write a + b + c instead of a.concatenate(b).concatenate(c). However, as a regular old user, operator overloading can be a drag. Let's say you come across the expression a + b. Are a and b numbers and are you adding them? Are they strings and are you concatenating them? Are they vectors and are you appending them? As a programmer, you don't know, so when you see this expression you have to go on a fact-finding mission to figure out what's going on. For a typed language like C++ this is not so bad; you just need to look up the types of a and b. But that isn't always straightforward due to type inference. The fact is that the symbol + has a well-defined meaning in mathematics. Operator overloading takes a very clear and well-defined symbol and turns it into a fuzzy enigma. In my opinion, it's better to have N well-defined, clear, and unique semantics for N symbols in a PL rather than having a single symbol that is overloaded for N purposes. Writing the code may take longer, but code is read more than it's written, so that doesn't seem so bad to me.
- FractalHQ 5y agoIn Typescript with VSCode just hovering over a variable shows its type and any doc comments with click-to-def. In that case, I don’t really see this being a problem.
- pjmlp 5y agoJust the same with a.concatenate(b).concatenate(c), how can you be sure what concatenate() is actually doing? One has to go through the same analysis the function called +.
- oldsecondhand 5y agoWith proper cross referencing tool support it can be the same, but in the past most IDEs didn't help you finding which function would be called in case of operator overload.
- ImprobableTruth 5y ago
- pjmlp 5y agoSame here, specially since they exist since Lisp.
- bradrn 5y agoPersonally I like the approach of Haskell: no overloading of any functions whatsoever (except in a restricted way through typeclasses), but you can define new operators yourself. That allows the certainty which comes with the absence of overloading, but also the concision which comes with using operators rather than functions. (Not that concision is everything, mind you; code gets difficult to read if there are too many custom functions. But at least the option is there.)
- alserio 5y agoI believe the Java people have done that in reaction to what was being done in c++ land. IMO operator overloading is fine when the operator is well behaved (i.e. respects some kind of law, plus should be at least a monoid etc).