# Splatting tuples into a named tuple implicitly converts them to pairs?

**URL:** <https://discourse.julialang.org/t/splatting-tuples-into-a-named-tuple-implicitly-converts-them-to-pairs/44351>\
**Category:** General Usage\
**Tags:** question, tuple\
**Created:** [August 5, 2020, 4:13pm UTC](https://discourse.julialang.org/t/splatting-tuples-into-a-named-tuple-implicitly-converts-them-to-pairs/44351 "2020-08-05T16:13:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [August 5, 2020, 4:13pm UTC](https://discourse.julialang.org/t/splatting-tuples-into-a-named-tuple-implicitly-converts-them-to-pairs/44351/1 "2020-08-05T16:13:51Z")

</div>

I was reading the docstring for `NamedTuple` and I discovered something odd. You can create a named tuple using pairs, like this:

```julia
julia> (; :a=>1, :b=>2)
(a = 1, b = 2)

```

Trying to do the same thing with tuples instead of pairs doesn’t work:

```julia
julia> (; (:a, 1), (:b, 2))
ERROR: syntax: invalid named tuple element "(:a, 1)"
Stacktrace:
 [1] top-level scope at REPL[3]:1

```

That’s not the surprising part. The surprising part is that splatting an array of tuples into a named tuple magically works:

```julia
julia> args = [(:a, 1), (:b, 2)];

julia> (; args...)
(a = 1, b = 2)

```

Given that `(; (:a, 1), (:b, 2))` does not work, I would think that splatting tuples into a named tuple would not work either. Is the splatting implicitly converting the tuples to pairs? I wouldn’t think that would be the case either, since splatting tuples into a dictionary doesn’t work (i.e., the tuples are _not_ converted to pairs):

```julia
julia> Dict(args...)
ERROR: MethodError: no method matching Dict(::Tuple{Symbol,Int64}, ::Tuple{Symbol,Int64})
Closest candidates are:
  Dict(::Any) at dict.jl:127
Stacktrace:
 [1] top-level scope at REPL[8]:1

```

Can anyone explain this apparent inconsistency?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [August 7, 2020, 12:29am UTC](https://discourse.julialang.org/t/splatting-tuples-into-a-named-tuple-implicitly-converts-them-to-pairs/44351/3 "2020-08-07T00:29:17Z")

</div>

you can splat a dictionary that has symbols as its keys

```julia
julia> dict = Dict([:integer => 1, :animal => "aardvark"])
Dict{Symbol,Int64} with 2 entries:
  :integer => 1
  :animal => "aarkvark"

julia> (; dict...)
(integer = 1, animal = "aarkvark")

```

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [August 7, 2020, 2:48am UTC](https://discourse.julialang.org/t/splatting-tuples-into-a-named-tuple-implicitly-converts-them-to-pairs/44351/4 "2020-08-07T02:48:36Z")

</div>

Ok, I think I figured it out. What I didn’t realize was that an iterator of 2-tuples works just as well as an iterator of pairs when splatting into the `kwargs...` slot of a function. This is true for any function of the form `f(<args>; kwargs...)`, not just named tuples.

First, some set up:

```julia
foo(; kwargs...) = kwargs;
bar(args...) = args;

args_pairs = [:a => 1, :b => 2];
args_tuples = [(:a, 1), (:b, 2)];

```

Now let’s compare `args_pairs` and `args_tuples`:

```julia
julia> foo(; args_pairs...)
pairs(::NamedTuple) with 2 entries:
  :a => 1
  :b => 2

julia> foo(; args_tuples...)
pairs(::NamedTuple) with 2 entries:
  :a => 1
  :b => 2

```

When they are splatted into keyword arguments, the iterator of pairs and the iterator of 2-tuples are exactly equivalent. However, when they are splatted into positional arguments, they are not equivalent:

```julia
julia> bar(args_pairs...)
(:a => 1, :b => 2)

julia> bar(args_tuples...)
((:a, 1), (:b, 2))

```

This is why `(; args_tuples...)` works and `Dict(args_tuples...)` does not work. The former splats the tuples into keyword arguments and the latter splats the tuples into positional arguments.
