This is the solution I use.
I believe you but I’m a bit surprised. By adding the interface f(nt:NamedTuple), you miss an opportunity of the compiler checking argument mismatch:
# -- in one module
function f(; x = "hello", y = 3.14, z = nothing)
@show x, y, z
end
f(nt::NamedTuple) = f(; nt.x, nt.y, nt.z)
function g(; x = "hello", y = 3.14, z = nothing)
@show x, y, z
end
read_data() = (x = "x", z = "z", y = "y")
# -- in the main program
vars = read_data()
nt = (; vars..., yy = "yy")
#^^^ I thought the name was "yy" and I didn't know that vars included "y".
f(; x = "x", z = "z", y = "y") # works
f(; x = "x", z = "z", yy = "yy") # error
f(nt) # no error
g(; nt...) # error
The problem of the f(nt:NamedTuple) interface is that extra variables are silently ignored.
Coming back to my original question: It’s tedious to write f(; x=vars.x, y=vars.y, . . .) What’s a more succinct way to write it?
We have two possible designs:
- Subset the original
NamedTupleand send it to the function asg(; subset...). - Write an extra interface to
fto take allNamedTuplesand send everything to the function asf(nt).
I would argue that design 1 is superior. For design 2, you have to write an extra interface f(nt:NamedTuple) and accept some possibility of argument mismatch.
Design 1 doesn’t have any drawback once you know how to subset a given NamedTuple.
The above is a contrived, stupid example, but I do make argument mismatch error from time to time. I sometimes include the same variable twice in the argument list by mistake and if I misspell one of them, the mistake would go unnoticed if it’s in a NamedTuple. And I do use NamedTuple to pass a set of arguments to a function.
This is not a fictitious scenario. Makie the graphics library accepts any keyword arguments and doesn’t check for misspellings, silently ignoring those it doesn’t recognize. As a result, it sometimes takes a lot of time to find out your misspellings.
In other words, I want to say, “this function requires this and that variables, not more”, not only in documentations, but I want to tell that to the compiler.