Open MaxGraey opened 2 years ago
One initial thought perhaps: Operator overloads are relatively unrestricted, i.e. an eq
is not required to return a bool
, respectively a ==
is not guaranteed to be an equals check at all. Would that lead to problems?
Yeah. Result type should be a bool
. Good point!
But now I'm wondering should we restrict overloadings ==
, !=
and etc to always be a bool
as a result?
Maybe a new operator overload is helpful <=>
similar as cpp https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison
I think for most of case it's enough. eq / le / ge
fulfills mathematical requirement.
The code should be like:
class Vec {
constructor(public x: f64 = 0, public y: f64 = 0) {}
norm2(): f64 {
return this.x * this.x + this.y * this.y;
}
// @operator("<=>")
private threeWayCmp(other: Vec): i32 {
const thisNorm2 = this.norm2();
const otherNorm2 = other.norm2();
return thisNorm2 - otherNorm2;
}
// automatically define by compiler:
@operator("==")
private eq(other: Vec): bool {
return this.threeWayCmp(other) == 0;
}
@operator("!=")
private ne(other: Vec): bool {
return this.threeWayCmp(other) != 0;
}
@operator(">")
private ge(other: Vec): bool {
return this.threeWayCmp(other) > 0;
}
@operator("<=")
private nge(other: Vec): bool {
return this.threeWayCmp(other) <= 0;
}
@operator(">")
private le(other: Vec): bool {
return this.threeWayCmp(other) < 0;
}
@operator("<=")
private nle(other: Vec): bool {
return this.threeWayCmp(other) >= 0;
}
}
Maybe a new operator overload is helpful <=>
It is not as universal as it may seem. For example, it won't work for unsigned int and floating points. Or rather, you will have to do rather non-trivial things to make it work. You can check it out here
What I mean is just adding a decorator @operator("<=>")
instead of adding a total new operator. The aim is that by this decorator, we don't need to write lots of similar compare code. It just a syntactic sugar.
Of course, your suggestion is more flexible but I think self-defined >=
<=
==
without mathematical meaning is very corner case.
it won't work for unsigned int and floating points I do not get the point why this design won't work for them.
For example, if we have custom
eq
we can always definane(a, b)
as!eq(a, b)
implicitly but only if operator marked as "private":similar to
>
/<=
and<
/>=
:In this case we can define minimal set to
==
,>
and<
to define full comparison domain. The rest can be overload optionally if behavior for!=
,<=
,>=
should be different