Hacker News new | ask | show | jobs
by pie_flavor 877 days ago
Native ints support math operators because math operators are far more readable than method calls. And if you're doing something that requires a custom numeric type, like base-10 floats or fixed-width, method calls don't get any more readable than math operators there either. A language where you can't overload numeric ops is a language with a strong disincentive against using better numerics. And this is without getting into having a single source of semantic equality, whether it be `==` or otherwise; not having that is probably the single worst design decision of Go.

This complaint is always made in the context of some pathological case where a library author tries to do clever things with operator overloading; if any such libraries exist in the first place, you can guarantee that you are not using them by simply not using any libraries with fewer than 10k downloads. The horror stories that fill HN comments pretty much never make it into real code.

1 comments

See my other comment about the necessity of clarity in a systems language. Also in my opinion readable code is code that is easily understood with as little context as possible. Operator overloading is the opposite, it hides behavior based on the types of the operands. Instead of thinking, that * will turn in to an smul, we now have to check for and read the implementation of * for every type. A function makes it clear that there is a call site and the types of its operands, and the name can more clearly convey the meaning of what is to be done than *.

What you are referring to as readability is actually terseness, which I think is a lousy metric to optimize for, especially for systems software where correctness is important and people will read code a lot more than they will write it.

I get where you're coming from, but I think it doesn't have to be more complicated than: "Are the two values standard Rust number types? If yes, they do simple multiplication on an asm level. Otherwise, check the relevant Mul implementation."
I disagree, consider a generic that is constrained by std::ops::Add. If you want to write generic functions with this type, you have to contend with types that might do simple addition or do allocations with potential side effects.
Why would you constrain a generic with ops::Add, if you didn't want to specifically allow for generic implementations of +? If you just want to be generic over built-in integers, it would be as easy as a "trait Integer: Add + Sub + Mul + TryFrom<i32> + ... {}" that's implemented by the standard integer types and sealed off from outside implementations.
As I understand it, generics are just a particular mechanism for interfacing with multiple types, and C manages without. For the same program, could a programmer ever be more unaware about which types are parameterized and which specific implementations are called in Rust than in C? I don't have much knowledge of C, admittedly, so this isn't a rhetorical question.
The whole point of generics is that you don’t know and don’t care what the type is.