Setting default arguments for a function passed to another function

I am defining a function that takes a keyword argument. I am setting a default function for this keyword argument, but I would like to also pass a default keyword to that second function. I am not sure how to do this.

For example, I would like to have something like:

function foo(X; fn = Statistics.mean)
    fn(X)
end

However, I would like to also set as a default the keyword argument dims = 1 for Statistics.mean. In other words, if the user calls foo(X), I want it to return Statistics.mean(x; dims = 1). As a user may pass a function that does not take a keyword argument dims = 1, I cannot add that directly to the line where fn is called. Is there a way to set a default argument of a default function on a keyword argument?

First, welcome!
You can just pass keyword arguments to the alias(?) name. You could also just trap the error if it is thrown if the user passes in a function that doesn’t have the needed keyword. Not necessarily a great way to do it, but if it absolutely needs to be designed this way …

function bar(X; baz)
    println("barring $X with $baz")
end

function zap(X)
    println("zapping $X")
end

function foo(X; fn=bar)
    try
        fn(X, baz="hi")
    catch e
        if isa(e, MethodError)
            @warn "you probably need to pass in a `fn` that has a `baz` keyword?"
        end
    end
end

foo(3)
foo(3, fn=zap)

prints:

barring 3 with hi
┌ Warning: you probably need to pass in a `fn` that has a `baz` keyword?
└ @ Main ~/Projects/Julia_C/C/stuff.jl:14
1 Like

If the default keyword argument only applies to the default function, just define that function accordingly, i.e.,

default_mean(x) = Statistics.mean(x; dims = 1)
function foo(X; fn = default_mean) fn(X) end

or simply

foo(X; fn = arg -> Statistics.mean(arg; dims = 1)) = fn(X)
2 Likes

Thank you. That works great