This came up on Slack the other day and I want to formalize a little proposal here. This is not possible, in terms of SemVer or by the compiler, currently.
Problem 1:
names = ["Roger", missing]
names[2] + 5
The second line should error, because no one’s name should ever really be a number. But this will return missing and propagate.
Problem 2:
[1, 2] + missing
I think most people imagine missing to be scalar-like values, numbers, strings, etc. The fact that this doesn’t error is un-intuitive.
Solution:
When defining a type, either Abstract or not, the package writer “ops-in” to missingness.
struct T
x
end
+(t::T, y) = t.x + y
struct S
x
end
+(s::S, y) = s.x + y
allow_missing!(S) # can now work with `missing`
T(1) + missing{T} # errors
S(1) + missing{S} # works
Now any function that accepts arguments of type S will also accept arguments of type missing{S} and they will propagate missing values.
We would define
allow_missing!(Number)
allow_missing!(AbstractString)
allow_missing(AbstractDate)
and then we would never have to worry about adding new methods to existing functions to propagate missing again.
There are obviously a lot of issues to work out. For instance, what about the following?
f(x, y) = (x, y)
f(missing{S}, 5)
clearly we don’t want the function to return missing. Rather, it should return (missing{S}, 5). Perhaps we can add a @propogate macro that will tell the function to pass along missing values. Or a @nopropogogate macro if the alternative is more common.