I would say that x === nothing and x isa Nothing are the same. In both cases, type inference is enough to determine whether the statement is true. (I personally find === easier to read.)
isnothing(x) has the advantage of allowing others to create types that are equivalent to Nothing to your code. (This might be useful for things like autodifferentiation, debugging, etc.)
x == nothing also has that advantage, but it makes type inference (edit: I mean dispatch) harder, because the == function takes two arguments.
Personally I like === as it brings back fond memories of Lisp (eq), but thatβs a style preference, the language does not care. In a situation with
abstract type NonResult end
struct NonConvergence <: NonResult end # only one subtype, but I may refactor later
const non_convergence = NonConvergence()
It is perhaps (just about) slightly interesting to look at the performance.
Among x === nothing, x isa Nothing and isnothing(x), === seems to be the fastest and isnothing() the slowest (timing).
This makes sense because checking for identity (=== pointer comparison) is quicker than checking a type, for the type has to be looked up in an internal table which causes a slight overhead. the function call is slower still for clear reasons.
This βanalysisβ is not worth much though, because firstly isnothing() is slightly different than the other two as it can be extended, while the other two are close enough that in a real program this would not make any difference. As such, I guess performance comparisons on this are little more than academic interest.
// Edit
if the object being compared is actually nothing, then isnothing() is much faster and about the same time of isa Nothing. Is isnothing(x::Nothing) perhaps inlined to just return true? It woud make sense and explains why it is just the same time as a type check.
julia> @which 5 == nothing
==(x, y) in Base at Base.jl:87
==(x, y) = x === y
julia> @which 5 === nothing
ERROR: ArgumentError: argument is not a generic function
So they are all the same unless thereβs a better method for the other operand, in which case that should probably be used. I donβt think thereβs any particular reason to use === for nothing, is there?.