Is there a convenient idiom to indicate that a keyword argument is absent? I imagine that somebody may have already invented a macro or something to do this . . .
There are library functions, typically from graphics packages, that take a large number of optional keyword arguments. Let’s call them “attributes”. If the user doesn’t specify them, such functions return convenient default results. This arrangement is very nice: the user typically needs to customize only a fraction of the attributes.
In this typical situation, how do you not give an attribute?
[In the following examples, func
is not a wrapper to the library function. It just uses the library function as part of its job.]
# Method 1
function func(; atB = nothing, ...)
... do something ...
if isnothing(atB)
libraryfunc(;atA=..., atC=..., ...)
else
libraryfunc(;atA=..., atB=atB, atC=..., ...)
end
end
# Method 2
function func(; atB = atB_default, ...)
... do something ...
libraryfunc(; ..., atB=atB, ...)
end
# Method 3: NamedTuple
function func(; atB = (), ...)
... do something ...
libraryfunc(; atB..., ...) # splat atB.
end
func(; atA=..., atB = (atB = somevalue,), atC=...)
func(; atA=..., atC=...)
Method 1 quickly becomes impossible if your function has multiple optional attributes.
Method 2 requires that you know the default value. Sometimes there are obvious default values but at other times, you have to consult the documentation, or in the worst case, you have to look at the source code. Moreover, the default value may change in the future. So, a question is, is there a method to query the default value of an optional keyword argument?
Method 3 is the only reliable method I’ve found so far. The downsize is that it’s a bit tedious on the caller side: you need to create a NamedTuple. An upside is that you can bundle multiple attributes into a single NamedTuple: ats = (atB=..., atD=...)
, where you can include or omit arbitrary attributes to libraryfunc()
.
But, I wish all library functions regarded nothing
as equivalent to not giving the argument. Or, can a macro be constructed in such a way that if the argument’s value is nothing
, it be removed from the argument list?