Also, I was thrown off by the following. Is this e...
# stdlib
s
Also, I was thrown off by the following. Is this expected?
Copy code
(Double.NaN == Double.NaN).let(::println) // false
(listOf(Double.NaN) == listOf(Double.NaN)).let(::println) // true
h
Not knowning the question here, I wonder why
.let(::println)
is not an extension in the stdlib
Any.println()
?
s
That would be a handy extensions but I've gotten used to writing
let(::println)
or
also(::println)
. The question here is, is it expected that
Double.NaN == Double.NaN
is
false
but when the value is wrapped in
listOf
it suddenly becomes
true
. I was assuming that the
equals
implemented by
List
would delegating to
Double#equals
. And if that is the case, why does
listOf(Double.NaN) == listOf(Double.NaN)
result in
true
.
h
I've just confirmed that it behaves the same for me. I also think it is odd/a bug. Maybe list equality is based on referential equality? This should be documented in the API docs I guess.
i
==
is not eqivalent to calling
equals
when comparing doubles
s
Thanks for clarifying @ilya.gorbunov! It feels a bit strange to me that
==
is not the same as
equals
😄 I thought
==
was a symbolic operator for
equals
but I guess that's not the case. Is this only different for floating-point numbers? Or are there other scenarios where
==
behaves differenrltly from
equals
?
h
Arn't the operands 
a
 and 
b
 are statically known in the example so that referential equality should be used?
s
Double.NaN === Double.NaN
also results in
false
.
t
One more example for Kotlin/JS
e
https://kotlinlang.org/docs/reference/basic-types.html#floating-point-numbers-comparison
However, to support generic use cases and provide total ordering, when the operands are not statically typed as floating point numbers (e.g.
Any
,
Comparable<...>
, a type parameter), the operations use the
equals
and
compareTo
implementations for
Float
and
Double
, which disagree with the standard, so that:
NaN
is considered equal to itself
NaN
is considered greater than any other element including
POSITIVE_INFINITY
-0.0
is considered less than
0.0
Seems like since
listOf(Double.NaN)
at runtime becomes
List<Any>
because of generic type erasure, equality will follow the rules above.