added a comment - - edited
Primitive comparisons use java's primitive operators directly, which always return false for NaN, even when testing equality between two NaNs.
In clojure, Number comparisons are all logical variations around calls to Numbers.Ops.lt(Number, Number). So a call to (<= x y) is actually a call to (not (< y x)), which eventually uses the primitive < operator. Alas that logical premise doesn't hold when dealing with NaN:
user=> (<= 1 Double/NaN)
user=> (not (< Double/NaN 1))
So the bug is not that boxed NaN is treated incorrectly, but rather:
user> (<= 1000 (Double. Double/NaN)) ; becomes !(NaN < 1000)
user> (<= 1000 (double Double/NaN)) ; becomes (1000 <= NaN)
In the original example, since there are more than two args, the primitive looking args were boxed:
user=> (<= 10 Double/NaN 1) ; equivalent to logical-and of the following
user=> (<= 10 (Double. Double/NaN)) ; becomes !(NaN < 10)
user=> (<= (Double. Double/NaN) 1) ; becomes !(1 < NaN)
Note however that java object comparisons for NaNs behave differently: NaN is the largest Double, and NaNs equal each other (see the javadoc).
If we make object NaN comparisons always return false, we would need to add the rest of the comparison methods to Numbers.Ops. Yet doing so could also make collection sorting algorithms behave oddly, deviating from sorting written in java. Besides, (= NaN NaN) => false is annoying.
Clojure already throws out the notion of error-free dividing by zero (which for doubles would otherwise result in NaN or Infinity, depending on the dividend). Perhaps we could similarly error on NaNs passed to clojure numeric ops. They seem to be more trouble than they're worth. That said, people smarter than me thought they were useful.
Then there's that -0.0 nonsense...