lisael
It's around since 2013 and was found in a unit test coverage improvement effort in Feb. 2018.
Given that pypy is mostly used for hard-core math and scientific computations, how the hell this bug wasn't found earlier by a user ?
My bet is that ZeroDivisionErrors are very rare. Do you even remember a ZeroDivisionError in production code ? I don't.
1/0 is my dirty little trick to add a breakpoint when I'm too lazy to launch a debuger. Why does this work? Here again, because nobody never catch ZeroDivisionErrors, because they don't happen.
So, what a fuss for such a tiny convention. Granted, it breaks the math correctness, as do ±Infinity. CPU integer math is broken anyway. In what world does 2^31 - 1 + 1 == -2^31 ?
I took a fairly large, used and old repository, Django and I search for ZeroDivisionError:
https://github.com/django/django/search?q=ZeroDivisionError&...
guess what:
- 4 occurrences in the tests
- 3 occurences in the issues
- last, but not least 1 occurrence in the code:
except ZeroDivisionError:
result = '0'If a==b and N≠0, then x==y
EDIT: Formatting
Therefore (2 + 1)/0 = 2/0 + 1/0 is not even false, it just means nothing.
BTW, you didn't mention Infinity explicitly, but it would lead to the same inconsistency, if you think about it:
(2 - 1)/0 = 2/0 - 1/0
:)
In [1]: 255 + 1 is 256
Out[1]: True
In [2]: 256 + 1 is 257
Out[2]: False
Every language has its inconsistencies, when it comes to math, because they run on real-world computers. All these are "slow" interpreted languages that allow runtime failures and don't use plain machine integers. Just a different trade-off.Anyway, the Inf/NaN trick is not better than the 0 trick in my opinion, because all subsequent operations result happily in NaN. I've never seen in any NaN language a program that checks for NaN the result of each and every division.
with a NaN-kind of language, it would be:
a = b/c
if a == NaN:
print "oops"
with a 0-trick language: a = b/c
if a == 0 and c == 0:
print "oops"
not THAT different, IMO :)Because of this rule, defining / as a partial function forces the user to fence every single division in a try clause.
Using boxed integer as Elm does is not an option as Pony targets high-speed computing, not browser rendering. Different fields, different trade-offs.
Defensive users can well define `div(I32, I32): I32?` that throws an error and use it instead of `/`.
As repeated in this thread, 1/0 is undefined because nonsensical. So, it's OK to have any sane, consistent and well documented behaviour. At least with Pony, the user can choose speed and convenience when they're sure there is no possible 0 at this place. Well, TBH, I think it's always the case. Because there is no such thing as a division by zero, you're algorithm is simply wrong and unsound if it ends up dividing by 0, and that's where this case differs from integer overflow
Note: in Pony literature, "partial" means "can throw an error". "partial" as in "doesn't apply to the whole domain of the arguments types"