# Vector{NamedTuple} vs Vector{@NamedTuple}?

**URL:** <https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111>\
**Category:** General Usage\
**Tags:** question, namedtuple, methods\
**Created:** [August 12, 2024, 9:41pm UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111 "2024-08-12T21:41:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 12, 2024, 9:41pm UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111/1 "2024-08-12T21:41:41Z")

</div>

How can I open my function method to work on all NamedTuples collected into a Vector? I don’t understand why this isn’t working.

```julia
function multicall(f::Function, user_inputs::Vector{NamedTuple}; kwargs...)
    out = []
    for input in user_inputs
        result = f(input; kwargs...)
        push!(out, result)
    end
    return out
end
export multicall

```

```julia-repl
julia> typeof(user_inputs)
Vector{@NamedTuple{fracture_operating_stress_file::String, fracture_residual_stress_file::String, crack_type::Symbol}} (alias for Array{@NamedTuple{fracture_operating_stress_file::String, fracture_residual_stress_file::String, crack_type::Symbol}, 1})

julia> multicall(compute_fracture_polys, user_inputs)
ERROR: MethodError: no method matching multicall(::typeof(compute_fracture_polys), ::Vector{@NamedTuple{…}})
The function `multicall` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  multicall(::Function, ::Vector{NamedTuple}; kwargs...)

```

The input was constructed within another function in a somewhat irregular way:

```julia
user_inputs = NamedTuple.(zip(allfiles...))

```

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [August 12, 2024, 9:45pm UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111/2 "2024-08-12T21:45:25Z")

</div>

Does replacing it (the signature) with `Vector{<:NamedTuple}` work?

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 13, 2024, 12:57am UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111/3 "2024-08-13T00:57:46Z")

</div>

Hmm, yes that fixes it.

I knew about using that for abstract types like `Vector{<:Real}`, but I didn’t think it was applicable for a `NamedTuple`. I thought `NamedTuple` was concrete because

```julia-repl
julia> subtypes(Real)
4-element Vector{Any}:
 AbstractFloat
 AbstractIrrational
 Integer
 Rational

julia> subtypes(Float64)
Type[]

julia> subtypes(NamedTuple)
Type[]

```

But I see now that it’s neither abstract nor concrete?

```julia-repl
julia> isabstracttype(NamedTuple)
false

julia> isconcretetype(NamedTuple)
false

```

So I don’t know what that means.

Better MWE:

```julia-repl
julia> function f(v::Vector{<:NamedTuple})
           return v
       end
f (generic function with 2 methods)

julia> nt = (; x=3, y=4)
(x = 3, y = 4)

julia> f([nt])
1-element Vector{@NamedTuple{x::Int64, y::Int64}}:
 (x = 3, y = 4)

```

@NamedTuple is a NamedTuple but NamedTuple is not a supertype of @NamedTuple?

```julia-repl
julia> nt isa NamedTuple
true

julia> supertypes(typeof(nt))
(@NamedTuple{x::Int64, y::Int64}, Any)

```

I’m not following how this works.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [August 13, 2024, 1:49am UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111/4 "2024-08-13T01:49:52Z")

</div>

`NamedTuple` is an `UnionAll`, not a `DataType`. Only `DataType` types may be concrete. (In fact, AFAIK only a `Tuple` type can be not concrete if it’s a `DataType`.)

There’s nothing special here about `NamedTuple`, so let’s take a simpler example, maybe that clears things up:

```julia-repl
julia> struct S{P} end

julia> S isa UnionAll
true

julia> S{Int} isa DataType
true

julia> s = S{Int}()
S{Int64}()

julia> typeof(s) == S{Int} <: S
true

julia> isconcretetype(S)
false

julia> isconcretetype(S{Int})
true

```

> [@Nathan\_Boyer](#):
>
> it’s neither abstract nor concrete

Yeah, abstract and concrete aren’t opposites. A type is “abstract” if and only if it’s declared with `abstract type`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 13, 2024, 5:45am UTC](https://discourse.julialang.org/t/vector-namedtuple-vs-vector-namedtuple/118111/5 "2024-08-13T05:45:12Z")

</div>

You can reason your way to this realization. If you know that a value is a `NamedTuple`, then what is the type of its first element? Since you cannot answer that question (nor look it up anywhere), the type isn’t fully specified.

With a concrete type, all the type info is known, including the type of each element.

It’s the same for `Vector`, without knowing the `eltype` you and the compiler lack crucial information about how to handle it.
