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.
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> 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:
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> 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> nt isa NamedTuple
true
julia> supertypes(typeof(nt))
(@NamedTuple{x::Int64, y::Int64}, Any)
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> 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
Yeah, abstract and concrete aren’t opposites. A type is “abstract” if and only if it’s declared with abstract type.
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.