Parametered optional named arguments

When I call the function

function f(;
    field        ::NTuple{Nfield,Symbol},
    fieldscale   ::NTuple= (),#NTuple{Nfield ,Float64}(1. for i =1: Nfield),
    afield       ::NTuple{Nafield,Symbol}=(;),
    afieldscale  ::NTuple= ()) where{Nfield,Nafield}  #NTuple{Nafield,Float64}(1. for i =1:Nafield)                ) where{Nfield,Nafield}
    @show Nfield,Nafield
end

with

f(field=(:a,))

I get

 MethodError: no method matching 
  var"#f#48"(::Tuple{Symbol}, ::Tuple{}, ::NamedTuple{(), Tuple{}}, ::Tuple{}, ::typeof(f))
Closest candidates are:
  var"#f#48"(::Tuple{Vararg{Symbol, Nfield}}, ::Tuple{Vararg{T, N}} where {N, T},
 ::Tuple{Vararg{Symbol, Nafield}}, ::Tuple{Vararg{T, N}} where {N, T}, 
::typeof(f)) where {Nfield, Nafield} at c:\...\try_parametered_optional_args.jl:5

And this puzzles me: First, the error message reports a call argument pattern which I haven’t used!. I’m innocent.

Besides, why does it fail at all? My call is with the named argument field and all other arguments are optional.

Thinking of it, I propose an answer: dispatch does not use named arguments, so a where statement on parameters to a keyword argument makes no sense, and I am being puzzled by a confusing compiler error. Is it? :grinning:

The default parameters don’t match the type

julia> typeof((;))
NamedTuple{(), Tuple{}}

This works

function f(;
    field        ::NTuple{Nfield,Symbol},
    fieldscale   ::NTuple= (),#NTuple{Nfield ,Float64}(1. for i =1: Nfield),
    afield       ::NTuple{Nafield,Symbol}=NTuple{0,Symbol}(),
    afieldscale  ::NTuple= ()) where{Nfield,Nafield}  #NTuple{Nafield,Float64}(1. for i =1:Nafield)                ) where{Nfield,Nafield}
    @show Nfield,Nafield
end

f(field=(:a,))

Oh heck, yes, having the default parameter of the right type is arguably a good idea!!!

Thank you Steffen!

1 Like