Canonical way to obtain `NamedTuple` from kwargs

I kept forgetting to ask this. Keyword args are returned as a Pairs iterator. This cannot be converted to a NamedTuple. The simplest way I can see to obtain a NamedTuple from this would be kwargs.data. Presumably this is not, however, a “public” value.

Is there some better way of obtaining the NamedTuple? Thanks in advance!

julia> test(;kw_args...) = values(kw_args)
julia> test(a = 22) |> typeof
NamedTuple{(:a,),Tuple{Int64}}

Nice, thanks. This probably should get documentation somewhere here, hopefully I’ll remember to make a PR…

I wonder, why kwargs is not a NamedTuple, any insights?

So you can iterate symbol => value.

Conversely, is there a canonical way to splat a named tuple as keyword arguments?

As far as I know this is just, for example

f(;n...)

No, that splats as positional arguments.

ulia> k = (a = 1, b = 2)
(a = 1, b = 2)

julia> f(x, y) = [x, y]
f (generic function with 1 method)

julia> g(;x=0, y=0) = [x, y]
g (generic function with 1 method)

julia> f(k...)
2-element Array{Int64,1}:
 1
 2

julia> g(k...)
ERROR: MethodError: no method matching g(::Int64, ::Int64)
Stacktrace:
 [1] top-level scope at none:0

You’re missing a semi-colon ;.

Ah, right, thanks.

If you ever get to that PR, please include this direction too, even if it is obvious when you’re awake enough.

How come they don’t execute with the same speed? (unrelated)

julia> using BenchmarkTools
julia>  f(x,y) = x+y*x
f (generic function with 1 method)

julia>  g(;x, y) = x+y*x
g (generic function with 1 method)

julia>  k = (x=2,y=32)
(x = 2, y = 32)

julia> @btime f(k...)
  114.007 ns (1 allocation: 112 bytes)
66

julia> @btime g(;k...)
  64.446 ns (1 allocation: 32 bytes)
66

julia> @btime f($k...)
  120.523 ns (2 allocations: 144 bytes)
66

julia> @btime g(;$k...)
  1.899 ns (0 allocations: 0 bytes)
66

Is because k is a global variable.

Tuples have special handling for splatting in the compiler which doesn’t currently seem to extend to NamedTuples

julia> kk = (2, 32)
(2, 32)

julia> @btime f($kk...)
  0.025 ns (0 allocations: 0 bytes)
66

doh yeah,

julia> const k = (x=2,y=32)
(x = 2, y = 32)

julia> f(x,y) = x+y*x
f (generic function with 1 method)

julia>  g(;x, y) = x+y*x
g (generic function with 1 method)

julia> @btime f(k...)
  140.377 ns (1 allocation: 112 bytes)
66

julia> @btime g(;k...)
  2.399 ns (0 allocations: 0 bytes)
66

julia> @btime f($k...)
  158.462 ns (2 allocations: 144 bytes)
66

julia> @btime g(;$k...)
  2.599 ns (0 allocations: 0 bytes)
66

Tuples have special handling for splatting in the compiler which doesn’t currently seem to extend to NamedTuples

is there an open issue for that?

I guess NamedTuple could be added to Performance of splatting a number · Issue #29114 · JuliaLang/julia · GitHub.