Welcome! Please see the About page for a little more info on how this works.

0 votes
in Java Interop by

The unary call for clojure.core// treats a dividend of 0.0 differently than the binary call, likely due to inlining.

(/ 0.0) ;; java.lang.ArithmeticException: Divide by zero (/ 1 0.0) ;;= Infinity (/ 1 (identity 0.0)) ;; java.lang.ArithmeticException: Divide by zero

4 Answers

0 votes
by

Comment made by: timmc

The relevant code seems to be this in clojure.lang.Numbers/divide:

if(yops.isZero((Number)y)) throw new ArithmeticException("Divide by zero");

Making Numbers/divide be more restrictive than double arithmetic seems like a bug; explicitly throwing an ArithmeticException instead of letting the JVM figure it just seems like more work than necessary.

0 votes
by

Comment made by: csm

I think the issue here is that in clojure.lang.Numbers, different variants of divide have different semantics. Numbers.divide(Object, Object) performs the isZero check, but Numbers.divide(long, double) does not (it just uses Java's division operator, which since the denominator is a double with value 0.0, produces Infinity).

A statement like (/ 1 0.0) gets compiled to call Numbers.divide(long, double), and thus produces Infinity. If the second argument is a function call or a var, it looks like an Object, so it gets compiled to use Numbers.divide(Object, Object), and that call throws when the second arg is zero (actually it compiles to a call to Numbers.divide(long, Object), but that just boxes the first argument and calls the other variant).

It does seem incorrect to have different semantics for division based on the inferred type at compile time; however, I don't know if this affects any other instance of division except divide-by-zero, so it's possibly not a practical problem.

0 votes
by

Comment made by: timmc

bq. I don't know if this affects any other instance of division except divide-by-zero, so it's possibly not a practical problem.

I regard code that only fails sometimes as worse, because then bugs are more likely to get caught in production instead of development.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1142 (reported by timmc)
...