NamedTuple constructor syntax

If I define a NamedTuple type like this

MyTupleType = NamedTuple{(:a, :b), Tuple{Float64, String}}
# or equivalently
MyTupleType = @NamedTuple{a::Float64, b::String}

I can use this to construct new named tuples with

mynamedtuple = MyTupleType((π, "hello"))

but not

mynamedtuple = MyTupleType(π, "hello")

Is there a good reason the constructor for the latter does not exist? It was how I assumed it should work and it took me a bit (well, like 20 minutes) to figure out that the former is the correct syntax.

It seems to me simply adding another constructor

NamedTuple{names,T}(args...) where {names,T<:Tuple} = NamedTuple{names,T}(Tuple(names))

should do the job. Are there some gotchas why this is not a good idea to have?

1 Like

Yes, there is. A NamedTuple is something that provides names to the elements of a tuple, this is the reason that a tuple is expected by the constructor.

In general, Julia does not provide a varargs version of constructors that expect a tuple or other collective data structure. This provides encouragement to provide the data structure that fits rather than an argument sequence.

You are welcome to define your own shortcut, be careful to check that the number of args matches the number of names. You should not overload NamedTuple (avoid type piracy). The functionality you seek is available with the package NamedTupleTools.jl :slight_smile:

There’s an ambiguity with the potential varargs namedtuple constructor: what should NamedTuple{(:a,)}((123,)) return? Is it (a=123,) or (a=(123,),)?

3 Likes