I think missing
is designed to silently propagate, as a data value that exists and is unknown, while nothing
is designed to be the absence of a data value, and not silently propagate. I think the intent is for missing
to be accepted by most functions that take normal values, while nothing
is not.
Also nothing
and missing
behave quite differently in comparisons, e.g.
julia> 1 == nothing
false
julia> 1 == missing
missing
julia> nothing == nothing
true
julia> missing == missing
missing
julia> 1 + missing
missing
julia> 1 + nothing
ERROR: MethodError: no method matching +(::Int64, ::Nothing)
Closest candidates are:
+(::Any, ::Any, ::Any, ::Any...) at operators.jl:502
+(::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}, ::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:53
+(::Union{Int16, Int32, Int64, Int8}, ::BigInt) at gmp.jl:456
...
Stacktrace:
[1] top-level scope at none:0