Maybe this is a dumb question, but there seems to be a bit of confusion about using ismissing(x) versus x === missing, and isnothing(x) versus x === nothing at [ANN] ShowLint - #3 by Mason.
I would say that in both cases, the functions are clearer for new Julia users. This is supported by the documentation for missing values (Missing Values · The Julia Language).
Using === (or !==) allows the compiler to disregard the other alternative type if the inferred type is e.g. a Union{Nothing, T}. Using == or isnothing does not allow this. https://github.com/JuliaLang/julia/pull/38905 might fix this though.
But Lint is not for new users only. I don’t think isnothing(x) should be advised against x === nothing. I have no intention to follow the suggestion and it would be another annoying red mark in the code when opened in VSC.
Is that because if x is of type T (rather than Nothing), isnothing(x) might not return a boolean value? In other words, isnothing(x::T) might be overloaded to not return a boolean? Or perhaps isnothing(x::T) is overloaded and for some reason the compiler cannot infer the return type of isnothing(x::T)? If the compiler can correctly infer the return type of isnothing(x::T), then I wouldn’t think that there would be a performance hit…
Are there really no zero-cost abstractions? I thought some abstractions ‘compiled away’ to produce the same machine code as the ‘inline’ code (like in inlined functions).
The TLDR of the talk is that there are 3 classes of cost: runtime, compile, and human. I think Julia does have a better argument for (basically) 0 cost abstractions in some cases. Our macros are a masterpiece of engineering, but still there is some nonzero compile time cost.
Admittedly, I didn’t watch the video. When I think of zero-cost abstractions, I basically mean run-time cost. I have the impression that this is pretty common.
Currently Julia has a unary == function defined so that ==(x) is y -> y == x. Why not also have a unary version of === so that isnothing can become ===(nothing), and the same for ismissing? This way nobody would be tempted to use ===(value, nothing) instead of the (superior?) value === nothing because the latter is obviously “more” correct. In comparison, it’s less clear at a glance which of isnothing(value) and value === nothing is preferable.
This does not make any difference in the curried form, since you are already introducing a function barrier which will inhibit constraint propagation anyways. The PR mentioned above has been merged though and will be in Julia 1.7, so the advice of always using x === missing will be obsolete soon.