Julia has two syntaxes for constructing named tuples.
The first syntax uses keys value pairs inside parenthesis with no semi-colon.
named_tuple = (a=1, b=2, c=3)
The second form of the syntax uses an initial semi-colon.
named_tuple = (; a=1, b=2, c=3)
As far as I can tell from the documentation both forms produce the same result. (A NamedTuple
object.)
There does not seem to be any difference between the following two forms.
julia> tuple1 = (a=1, b=2, c=3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple1)
@NamedTuple{a::Int64, b::Int64, c::Int64}
julia> tuple2 = (; a=1, b=2, c=3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple2)
@NamedTuple{a::Int64, b::Int64, c::Int64}
It appears to be possible to create a NamedTuple
from a series of pairs, but only if the semi-colon is included.
In other words, this syntax is valid and produces the expected result
julia> tuple3 = (; :a=>1, :b=>2, :c=>3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple3)
@NamedTuple{a::Int64, b::Int64, c::Int64}
on the other hand, the following does not
julia> tuple4 = (:a=>1, :b=>2, :c=>3)
(:a => 1, :b => 2, :c => 3)
julia> typeof(tuple4)
Tuple{Pair{Symbol, Int64}, Pair{Symbol, Int64}, Pair{Symbol, Int64}}
This produces a Tuple
of Pair
rather than a NamedTuple
.
What is the intended purpose for each form, or the reason for having two different forms?
The syntax (a=1, ...)
and (; a=1, ...)
are basically the same: both are named tuple constructors. One difference is that the second form lets you omit the comma and still have a named tuple, whereas (a=1)
is an assignment expression. Also, of course ()
is an empty tuple and (;)
is an empty named tuple.
The second form, with pairs, hooks into Julia’s keyword argument logic, which says that f(args; :a=>1, :b=>2)
passes keyword args a=1
and b=2
to f
. (This is mostly useful when you have something an iterator of symbol-value pairs, like a Dict, and want to splat...
it into keywords.)