Is there a standard way to add missing-propagation

By “add missing-propagation,” I mean making a function return missing if any one of its arguments is missing. So far the few times I wanted to do that, I add a one-liner method for each argument as type Missing, like so:

blah(x, y, z) = “blah” # example function
#added functions:
blah(x::Missing, y, z) = missing
blah(x, y::Missing, z) = missing
blah(x, y, z::Missing) = missing

You can see that can get tedious the more arguments a function has. I’m wondering if there’s some standard one-liner way to do this.
If not, I might get around to learning how to write macros. I’d be really thankful for tips like how to inspect existing methods for their number and names of arguments and how to define multiple nearly identical methods in a macro.

1 Like

There is Missings.passmissing as a wrapper, but also note that

function blah(x, y, z)
    if any(ismissing, (x, y, z))
        missing
    else
        "blah"
    end
end

also compiles to efficient code.

2 Likes

This could be a nice case for a macro, but I wouldn’t make it as complex as you’re suggesting. Instead, you could write a macro that makes use of the passmissing function that @Tamas_Papp suggested. For example, given a function like:

julia> function f(a, b, c)
         a + b + c
       end

You could write a macro that instead produces this code:

 julia> function f(a, b, c)
         passmissing(function f(a, b, c)
           a + b + c
         end)(a, b, c)
       end

which gives:

julia> f(1, 2, 3)
6

julia> f(1, 2, missing)
missing

julia> f(missing, 2, 3)
missing

This looks a bit weird, but all I’m doing is passing the original function definition to passmissing and then calling the result on the arguments (a, b, c). The nice thing about this is that the transformation from the original function syntax to the modified one should be easy to do programmatically (and thus this is a good case for a macro).

3 Likes