Subset a NamedTuple?

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:

  1. Subset the original NamedTuple and send it to the function as g(; subset...).
  2. Write an extra interface to f to take all NamedTuples and send everything to the function as f(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.