Hacker News new | ask | show | jobs
by masklinn 2557 days ago
> The third was that js has no operator overloading, so I had to use .__add__() for example to call the python add operator.

I expect this wouldn't have worked in the long run as these methods are often just part of the protocol e.g. even `a == b` will try `type(a).__eq__(a, b)` then fall back to `type(b).__eq__(a)` (~~and then it'll do some weird stuff with type names IIRC~~[0]).

And most operators are not considered symmetric so the fallback is not the same as the initial (even `+` has `__add__` and `__radd__`, also `__radd__` might be called first depending on the relationship between type(a) and type(b)).

And then there's the "operations" which fallback to entirely different protocols e.g. `in` will first try to use `__contains__`, if that doesn't exist it uses `iter()` which tries to use `__iter__` but if that doesn't exist it falls back to calling `__getitem__` with non-negative sequential integer.

Which is why sometimes you define `__getitem__` for a pseudo-mapping convenience and then you get weird blowups that it's been called with `0` (you only ever expected string-keys). Because someone somewhere used `in` on your object and you hadn't defined `__iter__` let alone `__contains__`.

Good times.

[0] I misremembered: it's for ordering (not equality) in Python 2[1] `a < b` will first invoke `type(a).__lt__(a, b)`, then if that's not implemented fall back to `type(b).__ge__(a)`, and if that's not implemented either it'll fall back to a few hard-coded cases (e.g. None is smaller than everything) and finally to `(type(a).__name__, id(a)) < (type(b).__name__, id(b))`. That is the order of independent types with no ordering defined is the lexicographic order of their type names, and if they're of the same type it's their position in memory

[1] where there's always an ordering relationship between two objects, one of the things I'm most graceful Python 3 removed even if it's sometimes inconvenient