It's instructive to look at the result of:
(let [ones [1 1.0 1N 1M 1.0M] ] (for [a ones b ones] (== a b)))
The first four compare equal in all combinations. 1.0M is equal to 1.0
but unequal to all the others.
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)
> I'd also like to make sure people are aware of this oddity. I
> discovered this after reading an article about the bad design of PHP.
> I read that in PHP, "== is not transitive." I thought "Ha ha ha, that
> ridiculous PHP!"
>
> Then I checked c.c/== ; Imagine my reaction when I learned that
> Clojure had something in common with PHP. o_O, :'[ Other emoticons
> also washed over me.
Clojure's == is numerical equivalence, not equality.
-------------------------
clojure.core/==
([x] [x y] [x y & more])
Returns non-nil if nums all have the equivalent
value (type-independent), otherwise false
The problem with PHP (and JavaScript's) == operator is that the type
coercion is not limited to numerical types:
PHP
"1" == 1 => true
"1" + 1 => 2
JavaScript
"1" == 1 => true
"1" + 1 => "11"
Clojure
(== "1" 1) => java.lang.ClassCastException
(+ "1" 1) => java.lang.ClassCastException
Clojure's equality function [1], however, does what you expect when
comparing floats and integers:
(= 1.0 1) => false
But it also does what you want when comparing _categories_ of numbers
[2] [3]:
(let [a (int 1) b (bigint 1)]
{:equal_values? (= a b)
:equal_types? (= (type a) (type b))})
=> {:equal_values? true, :equal_types? false}
I think Clojure does a fantastic job of being both convenient and
strongly typed.
--
guns
[1]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L23
[2]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L213
[3]: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L978
If you were really concerned about whether a number is a BigInteger
vs Integer, or Float vs Double, you would have to handle that on
your own.
I must agree that the behaviour of == is not correct here.