# Named Tuple Constructor type unstable?

**URL:** <https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461>\
**Category:** General Usage\
**Created:** [April 24, 2019, 12:13am UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461 "2019-04-24T00:13:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bjack205](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjack205/32/7294_2.png) [@bjack205](https://discourse.julialang.org/u/bjack205)\
**Post date:** [April 24, 2019, 12:13am UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/1 "2019-04-24T00:13:44Z")

</div>

I’m getting some odd type instability when using the NamedTuple constructor

```julia
NamedTuple{symbol}(values)

```

Here’s a simple example:

```julia
using IteractiveUtils
names = (:x,:y)
vals = (rand(2,2), rand(2,2))
create_nt(names,vals) = NamedTuple{names}(vals)
create_nt(vals) = NamedTuple{(:x,:y)}(vals)

```

checking for type stability returns

```julia
julia> @code_warntype create_nt(names,vals)
Body::Any
1 ─ %1 = (Core.apply_type)(Main.NamedTuple, names)::Type{NamedTuple{_1,T} where T<:Tuple} where _1
│ %2 = (%1)(vals)::Any
└── return %2

julia> @code_warntype create_nt(vals)
Body::NamedTuple{(:x, :y),Tuple{Array{Float64,2},Array{Float64,2}}}
1 ─ %1 = (Core.getfield)(vals, 1)::Array{Float64,2}
│ %2 = (Core.getfield)(vals, 2)::Array{Float64,2}
│ %3 = %new(NamedTuple{(:x, :y),Tuple{Array{Float64,2},Array{Float64,2}}}, %1, %2)::NamedTuple{(:x, :y),Tuple{Array{Float64,2},Array{Float64,2}}}
└── return %3

```

This is very puzzling behavior to me. Why can’t I pass in an external tuple of symbols? This makes dynamically creating NamedTuples very difficult. Is there another constructor I should be using?

Thanks!

Running Julia 1.1 on Linux Mint

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 24, 2019, 5:37am UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/2 "2019-04-24T05:37:09Z")

</div>

If you think about it, the names are part of the type (they are type parameters), so unless they are known at (AOT) compile time, they will be considered dynamic. This is not special to `NamedTuple`.

The solution would depend on the context. Ideally, the names would come from another type parameter, perhaps from another `NamedTuple`. You can also use a `NamedTuple{(:x,:y)}` type for this purpose; eg see the source of `Base.structdiff`.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 24, 2019, 12:46pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/3 "2019-04-24T12:46:18Z")

</div>

Your example is actually a textbook definition of type unstable code. A NamedTuple’s type includes the field names, and you are passing in those field names as the value of an argument. Thus you have a return _type_ which depends on the _value_ of an argument.

If you can give some more context on the problem you actually want to solve, perhaps we can suggest an alternative. It may be that you can pull the field names out of some other type, as @Tamas_Papp suggests, or it may be that you actually want something more like a Dict with Symbol keys.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [April 24, 2019, 1:08pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/4 "2019-04-24T13:08:02Z")

</div>

> [@Tamas\_Papp](#):
>
> If you think about it, the names are part of the type (they are type parameters), so unless they are known at (AOT) compile time, they will be considered dynamic.

To complement this, note that the names have to be part of the type, so that in type-stable code, the meaning of `nt.x` can be known at compile time.

---

<div class="post-metadata">

**Author:** ![bjack205](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjack205/32/7294_2.png) [@bjack205](https://discourse.julialang.org/u/bjack205)\
**Post date:** [April 24, 2019, 3:37pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/5 "2019-04-24T15:37:56Z")

</div>

Thanks guys! Makes total sense.  
My actual use case is for a package I’ve been working on that stores a matrix with a set of pre-defined views, useful for “partitioned” matrices where you frequently access the same views but still want to store the array as a whole (in contrast to BlockArrays.jl which stores a list of blocks).

Essentially the type allows you to do `A.x` or `A[:x]` instead of `A[4:10,6:15]`

My data type is

```julia
struct BlockArray{T,N,M<:AbstractArray{T,N},P<:NamedTuple} <: AbstractArray{T,N}
    A::M
    parts::P
end

```

where `parts` is a NamedTuple of indices used to create views.  
I was trying to use NamedTuples rather than a Dictionary since they seemed to be faster, but maybe I should just go with a Dictionary to simplify things.

I run into the type stability problem when creating these NamedTuples dynamically, given a particular “partition” and what you want the name of the partitions to be.

---

<div class="post-metadata">

**Author:** ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)\
**Post date:** [April 24, 2019, 3:38pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/6 "2019-04-24T15:38:07Z")

</div>

> [@bjack205](#):
>
> @code\_warntype create\_nt(vals)

Yeah, what others have said here is correct. Now, there are cases where constant propagation could get fancy and figure out that you’re passing in constant symbols and maybe figure out the NamedTuple type from those. The other way to do something like this, if you do in fact know the symbols ahead of time is to pass a `Val{names}`, something like:

```julia
create_nt(::Val{names}, vals) where {names} = NamedTuple{names}(vals)

# called like
create_nt(Val((:x, :y)), (1.0, 2.0))

```

---

<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:** [April 24, 2019, 4:14pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/7 "2019-04-24T16:14:23Z")

</div>

right, and as NamedTuples with given `names` often are reused, with your defs  
`create_xy(vals) = create_nt(Val{(:x, :y)}, vals)`  
`create_xy(vals...) = create_nt(Val{(:x, :y)}, vals)`

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 24, 2019, 4:34pm UTC](https://discourse.julialang.org/t/named-tuple-constructor-type-unstable/23461/8 "2019-04-24T16:34:41Z")

</div>

Got it. A `Dict` will probably work quite well, but this also might be a case where some type instability is totally fine. It’s often fine to have a piece of type-unstable code, as long as you can isolate that instability. For example, if your code looks like:

```julia
function f()
  b = BlockArray(...)
  g(b)
end

function g(b)
  < do something with b >
end

```

then `b` will be type-unstable inside `f()`, sure, but Julia will still call the correct specialization of `g(b)` for whatever type it actually has. That means that inside `g(b)` this is _no penalty at all_ for the fact that `b` came from a type-unstable source.

So, as long as your function that uses the `BlockArray` is moderately expensive, the time you spend dealing with type-instability in `f()` may be completely negligible.

By the way, the general term for this in Julia is a “function barrier”.
