Function select only compatible args

In my opinion it would be nice if this could be done directly, :

f1(a1; a2=1, a3="a") # a4, a5, ...
f2(b1; b2='k', b3=2.0) # b4, b5, ...

function f(x, y, z, a1, b1; kwargs...)
    # code
    f1(a1; kwargs...) 
    # code
    f2(b1; kwargs...)
    #code
end

where f1 and f2 have different kwargs, and each function automatically chooses only compatible kwargs.
Wrapping of functions would be greatly simplified.
Currently doing something like this is a bit complicated, and it has to be done by hand for each function called in f.
What do you think about it?

You can try this:

f1(a1; a2=1, a3="a", kw...) = println("a2: ", a2, ", a3: ", a3)
f2(b1; b2='k', b3=2.0, kw...) = println("b2: ", b2, ", b3: ", b3)

function f(x, y, z, a1, b1; kwargs...)
    # code
    f1(a1; kwargs...) 
    # code
    f2(b1; kwargs...)
    #code
end

f1 and f2 slurp and discard unused args in kw, so they actually do automatically choose only compatible kwargs now.

1 Like

f1 and f2 come from a Pkg.

I don’t have an answer in that case. There is a related discussion here: Finding possible keyword arguments
(I messed up the link at first. Scroll to the top.)

1 Like

It’s not pretty, but perhaps this will work:

f1(a1; a2=1, a3="a") # a4, a5, ...
f2(b1; b2='k', b3=2.0) # b4, b5, ...

function f(x, y, z, a1, b1; kwargs...)
    # code
    f1(a1; a2=get(kwargs,:a2,1), a3=get(kwargs,:a3,"a")) 
    # code
    f2(b1; b2=get(kwargs,:b2,'k'), b3=get(kwargs,:b3,2.0))
    #code
end

There are cleaner ways that would involve subselecting your initial kwargs to produce ones that only have the desired subset of values for each call, but this could work.

Alternatively, you could do something like this

function f(x, y, z, a1, b1; f1kw = NamedTuple(), f2kw=NamedTuple())
    # code
    f1(a1; f1kw...) 
    # code
    f2(b1; f2kw...)
    #code
end

f(1, 2, 3, 4, 5; f1kw=(a2=6,), f2kw=(b3=2.5,b2='j'))

@DNF
Can adding kwargs… to all the functions I’ve written cause performance issues?
In general, is it a good practice to write functions that accept kwargs which are then not used?

Could someone give me an example of how I can write a macro that takes the function and passes to the called functions only compatible named arguments?

You could also try using select from NamedTupleTools.jl. Something like:

function f(x, y, z, a1, b1; kwargs...)
    f1(a1; select(NamedTuple(kwargs), (:a2, :a3))...)
    f2(b1; select(NamedTuple(kwargs), (:b2, :b3))...)
end

That might be easier if you have to forward a lot of keyword arguments.