if you can act on the original function, you can set it this way and then be able to add new methods with different kwargs
nt1=(; c=1, d=2.0, e="hello")
function f(a::Number, b::Number,nt :: typeof(nt1))
println(nt.e, '\n', a+b, '\n', nt.c*nt.d)
end
f(3, 2 ,nt1)
nt2=(; f="bye", g=pi, h=nothing)
function f(a::Number, b::Number, nt::typeof(nt2))
println(nt.f, '\n', a+b, '\n', isnothing(nt.h) ? 2*nt.g : nt.g/2)
end
f(3, 2, nt2)
PS
I’m not very confident that what has been proposed above makes much sense, in general.
Edit: Can someone of good will and good knowledge explain why it doesn’t work
julia> nt2=NamedTuple{(:f, :g, :h), Tuple{String, Irrational{:π}, Any}}((f="bye", g=pi, h=nothing))
NamedTuple{(:f, :g, :h), Tuple{String, Irrational{:π}, Any}}(("bye", π, nothing))
julia> function f(a::Number, b::Number, nt::typeof(nt2))
println(nt.f, '\n', a+b, '\n', isnothing(nt.h) ? 2*nt.g : nt.g/2)
end
f (generic function with 1 method)
julia> f(3, 2, nt2)
bye
5
6.283185307179586
julia> Tuple{String, Irrational{:π}, Nothing} <: Tuple{String, Irrational{:π}, Any}
true
julia> Tuple{String, Irrational{:π}, Number} <: Tuple{String, Irrational{:π}, Any}
true
julia> nt=merge(nt2, (f="addio",h=9))
(f = "addio", g = π, h = 9)
julia> f(5,4,nt)
ERROR: MethodError: no method matching f(::Int64, ::Int64, ::NamedTuple{(:f, :g, :h), Tuple{String, Irrational{:π}, Int64}})
Closest candidates are:
f(::Number, ::Number, ::NamedTuple{(:f, :g, :h), Tuple{String, Irrational{:π}, Any}}) at c:\Users\sprmn\.julia\environments\v1.8.3\functions2.jl:88
Stacktrace:
[1] top-level scope
@ c:\Users\sprmn\.julia\environments\v1.8.3\functions2.jl:100
Is it possible to have a NamedTuple as a subtype of a more generic namedtuple?