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
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