I have a function with some optional keyword arguments.
function f1(a::Int, b::Float64; c::Int=42, d::Int=43)
Another top level function may sometimes call f1, but I don’t want to bother the user with specifying f1’s arguments if they’re not necessary. And when the arguments are required, I want to make it as easy to manage as possible.
This is my partial solution so far
function f_top(call_f1::Bool; f1_params::Union{Tuple,Nothing}=nothing)
if call_f1
isnothing(f1_params) && throw(ArgumentError)
f1(f1_params...)
end
end
function f_top(call_f1::Bool; f1_params::Union{Tuple,Nothing}=nothing, f2_kwargs...)
if call_f1
isnothing(f1_params) && throw(ArgumentError)
f1(f1_params...; f2_kwargs...)
end
end
with f1(a::Int, b::Float64; c::Int=42, d::Int=43) = a+b+c+d
For many keyword arguments that are passed around/downstream this way, it is common to wrap them in a struct defined for the purpose. Base.@kwdef provides a nice interface for construction.
julia> Base.@kwdef struct Params
a :: Int # Mandatory arguments
b :: Float64
c :: Int = 42 # Optional arguments with a default value
d :: Int = 43
end
Params
julia> function f1(p::Params)
# get the arguments values from the fields of p
p.a * p.b + p.c - p.d
end
f1 (generic function with 1 method)
# instantiate a set of parameters
# (c will get its default value)
julia> p = Params(a=1, b=3.14, d=12)
Params(1, 3.14, 42, 12)
# call f1 with these parameters
julia> f1(p)
33.14
Beware: IIRC Base.@kwdef is not part of Julia’s public API