I guess it’s better in terms of performance and pr...
# announcements
m
I guess it’s better in terms of performance and predictability to use
!== null
and
=== null
instead of
!= null
and
== null
due to not using
equals
?
s
Note that there’s no point in optimizing your code when comparing to 
null
 explicitly: 
a == null
 will be automatically translated to 
a === null
https://kotlinlang.org/docs/reference/equality.html#structural-equality
m
Interesting, thanks! I’ll open an issue to add an inspection that encourages to replace
=== null
and
!== null
then 🙂
s
I think there is one exception to the rule. If left-hand side has
dynamic
type, equality operators would be translated to corresponding JS
a == null
or
a === null
. First one would be true if
a
is
null
or
undefined
. Second would strictly check for
null
.
😮 1
I tested it a bit more, looks like above is true for all left-hand side types in Kotlin/JS, not only `dynamic`s. 🙃
m
I guess you mean only nullable types? They can be
undefined
?
And what happens if a nullable JS value is passed to common code? Will
undefined
suddenly turn into
null
or will equality in common code suddenly change meaning?
s
Both
undefined
and
null
JS values are treated as
null
in Kotlin (Apparently except in
===
). Kotlin
null
is represented as JS
null
, but
undefined
could come from interop.
m
Yes, but when developing common code you probably won’t expect a
null
value that isn’t identical to
null
.
s
To answer your question,
===
would change the meaning in common code. Everything else should work fine.
m
lol, Kotlin JS is quite messy!
Copy code
fun main() {
    var x: String? = undefined
    
    if (x !== null)
    	println(x.toUpperCase())
}
Unhandled JavaScript exception: Cannot read property 'toUpperCase' of undefined
s
Its a valid concern, definitely something to think about. However there are trade-offs. Normalizing nulls at interop boundaries can be expensive if nulls are deeply nested inside object graph. Also both undefined and null are common way to represent absent value in JS, so it would be inconvenient to support only one of them. In order to support common semantic in
===
we would need to put null-checks on every
===
with nullable types on both sides. But people expect
===
to be very fast.
m
Treating
=== null
as
== null
would only have to be done in JS code, wouldn’t it? Is there a performance difference in that case? From a Kotlin perspective it would probably be much more reasonable, consistent and predictable if
undefined
is always treated as
null
in equality and identity checks. Developers can still check
=== undefined
. No normalization needed then.
s
Treating
=== null
as
== null
is relatively cheap indeed. But treating
a === b
as
a == b
, where a and b are nullable, would break identity semantics due to coercion rules in JS. You would have to translate
a === b
to something like
a == null ? b == null : a === b
which could be a performance problem.
m
Ah, true. But I guess that would be a much rarer occasion and only if both sides are nullable. Still sounds like a very good trade-off to keep other identity checks as-is and only handle identity checks against
null
.
Or just take the performance hit in these edge cases. Worst case an intrinsic can be provided for the few cases where that performance matters. Like
jsIsIdentical(a, b)
or similar.
s
Agree. Special case for
=== null
would at least solve the smart cast problem you mentioned.