4 ms·
I re-read your comment a couple times, and understood your main point to succinctly be this: If `Point` is a subclass of `ColoredPoint`, and `p` and `cp` exist
by dfee 8y ago
I re-read your comment a couple times, and understood your main point to succinctly be this:
If `Point` is a subclass of `ColoredPoint`, and `p` and `cp` exist as instances respectively, there is ambiguity between `p == cp` and `cp == p`.
In Python there is first class support for operators: the `eq` dunder method:
def __eq__(self, other):
if not isinstance(other, type(self)):
return False
return self.point == other.point
This ambiguity is hard to solve around.
- dnomad 8y agoThis doesn't really solve the ambiguity. You can do the same in Java (and people often do): if (getClass() != other.getClass()) return false; This does guarantee that equality is symmetric but it's also troublesome. First, you have to trust everybody to do this comparison. If one type forgets then symmetry breaks. But also, sometimes, in the case of value objects like Points you do want equality between different types. Point2D and Point3D and RasterPoint all have x,y coordinates and should be equatable. The proposal is to capture equality (and all other operators) as static methods. class Point2D { public static boolean operator_equals(Point2D p1, Point2D p2) { ... } } class ColoredPoint { public static boolean operator_equals(ColoredPoint cp, Point2D p2) { ... } } In certain cases the compiler can unambiguously determine that there is a single static method that defines equality then this can be invoked by 'a == b' and we can also be sure that 'b == a' because both refer to the same method. The point here is that equality is not something that can be decided by one object, it is an operator that establishes relations between types of objects. There's a very fundamental difference between sending a message to a single object and establishing a relation and this is the source of all the confusion around equality.
- repsilat 8y agoA solution was suggested by the grandparent: make `a==b` call both equality methods. Dunno if you raise or just return false if they disagree.
- munificent 8y agoI was working on a hobby language a few years ago and trying to figure out a way to handle equality to avoid these problems. One solution I considered was: 1. Ask the LHS for its equality function. 2. Ask the RHS for its equality function. 3. If the two return different functions (non-identical), the objects are not equal. 4. Otherwise, return the result of invoking the function. The first two steps are polymorphic, so objects can define interesting equality semantics with whatever policy makes sense for them. But step 3 ensures that the two objects must agree on that policy before you can compare them.
- repsilat 8y ago> One solution I considered It sounds pretty reasonable, but I have no idea how "sounds reasonable" correlates with "is helpful in practice". (I think one of the commenters in the linked page might have raised that point too.) Fulfilling axioms of equality definitely does sound useful for being able to write code, though -- having symmetry, not having to think about whether you need to write `a==b` or `b==a`, seems like it'd lighten the cognitive load. I suppose also when the objects disagree about equality you also have some license to say "this may not do quite what you expect" and do your best to make the most of it. > I was working on a hobby language a few years ago Hah, you're famous enough that we've all probably heard of the language if it has seen the light of day ;-). My own hobby language has no methods or dynamic dispatch of any kind, haha. It's a little stressful to have to come up with some equality rule that works for essentially every use-case, though -- I don't think it's sufficient to enumerate the data types in the language, I really have to go over all the ways I think they could be used :-/. Oh well, it's fun at least.