let check_exp (g : Elliptic_curve_pt.t) (x : int) (y : int) = let xy = x * y in let open Elliptic_curve_pt.Num_syntax in (g ^ x) ^ y = g ^ xy
This lets you avoid making hard decisions about what can be added/multiplied/etc. at the language level -- can a list of numbers representing the coefficients of a polynomial be added? -- without jumping to the extreme of allowing anything implicitly. This also lets the typechecker catch more of your mistakes by having stricter types, and means you know exactly where to go to find out what the syntax is encoding.
Elliptic_curve_pt.Num_syntax.( (g ^ x) ^ y = g ^ xy )
instead of let open Elliptic_curve_pt.Num_syntax in ...I agree. That's why D uses a separate operator for concatenation, ~=
That removes the temptation to overload +=.
In short... math isn't just arithmetic, isn't even arithmetic of complex tensors. Math is way bigger than most programmers seem to comprehend. I'm on the other side of the DK curve; I know that I've only scratched the surface despite a decade of dedicated study
As for abuse prevention: it would be impossible to use the common operators like +, -, +=, <<, >> and so on for anything that is not numbers, and therefore prevent C++ levels of overloading abuse.
class MyString extends Number
and you get access to operator overloads. Only thing that makes this annoying is Javas lack of multiple inheritance, but that is pretty minor thing.
Limit operator overloading to classes that extend Number and 90% of the excesses of operator overloading are impossible.
You probably shouldn’t be using += for your concatenation code anyway (interpolation is often more powerful). The only other place you will “miss” it is in data types that are vector values, and you could probably figure out a rule for that in a later iteration.