Arrays of NamedTuples with Arrays in Julia 0.7


#1

I am trying to create an Array with named tuples inside where one of the fields is an array. In 0.6 this is possible

a = @NT(t = 10, x = [1,2])
b = @NT(t = 1, x = [23,3])
m = [a,b]

However, in Julia 0.7 I get this error

m = (a=10, b=[1,2])
m2 = (a=10, b2=1)
[m,m2]

type UnionAll has no field name

Stacktrace:
 [1] getproperty at ./sysimg.jl:15 [inlined]
 [2] typeinfo_prefix(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Int64,1}) at ./arrayshow.jl:477
 [3] show_vector(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Int64,1}, ::Char, ::Char) at ./arrayshow.jl:431 (repeats 2 times)
 [4] show at ./arrayshow.jl:417 [inlined]
 [5] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}) at ./namedtuple.jl:142
 [6] #sprint#330(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Int64, ::Function, ::Function, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}) at ./strings/io.jl:97
 [7] #sprint at ./none:0 [inlined]
 [8] alignment(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}) at ./show.jl:1719
 [9] alignment(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{NamedTuple,1}, ::Base.OneTo{Int64}, ::Base.OneTo{Int64}, ::Int64, ::Int64, ::Int64) at ./arrayshow.jl:68
 [10] print_matrix(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{NamedTuple,1}, ::String, ::String, ::String, ::String, ::String, ::String, ::Int64, ::Int64) at ./arrayshow.jl:186
 [11] print_matrix at ./arrayshow.jl:159 [inlined]
 [12] print_array at ./arrayshow.jl:308 [inlined]
 [13] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::MIME{Symbol("text/plain")}, ::Array{NamedTuple,1}) at ./arrayshow.jl:344
 [14] limitstringmime(::MIME{Symbol("text/plain")}, ::Array{NamedTuple,1}) at /Users/jdlara/.julia/packages/IJulia/Nnq2/src/inline.jl:24
 [15] display_dict(::Array{NamedTuple,1}) at /Users/jdlara/.julia/packages/IJulia/Nnq2/src/execute_request.jl:28
 [16] #invokelatest#1 at ./essentials.jl:670 [inlined]
 [17] invokelatest at ./essentials.jl:669 [inlined]
 [18] execute_request(::ZMQ.Socket, ::IJulia.Msg) at /Users/jdlara/.julia/packages/IJulia/Nnq2/src/execute_request.jl:208
 [19] #invokelatest#1 at ./essentials.jl:670 [inlined]
 [20] invokelatest at ./essentials.jl:669 [inlined]
 [21] eventloop(::ZMQ.Socket) at /Users/jdlara/.julia/packages/IJulia/Nnq2/src/eventloop.jl:8
 [22] (::getfield(IJulia, Symbol("##15#18")))() at ./task.jl:257

is there any way around it or is it a feature?


#2

[m,m2] works. The array is created. The error is on showing the result. Looks like a bug. Mind filing an issue?


#3

Here’s a bit more detail:

julia> c = [m,m2];

julia> c[1]
(a = 10, b = [1, 2])

julia> c[2]
(a = 10, b2 = 1)

julia> c[[2]]
1-element Array{NamedTuple,1}:
 (a = 10, b2 = 1)

julia> c[[1]]
1-element Array{NamedTuple,1}:
Error showing value of type Array{NamedTuple,1}:
ERROR: AssertionError: Array{Int64,1} is not a subtype of NamedTuple
Stacktrace:
 [1] typeinfo_prefix(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Int64,1}) at .\arrayshow.jl:480
 [2] show_vector(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Int64,1}, ::Char, ::Char) at .\arrayshow.jl:433 (repeats 2 times)
 [3] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Int64,1}) at .\arrayshow.jl:447
 [4] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}) at .\namedtuple.jl:82
 [5] #sprint#312(::IOContext{Base.Terminals.TTYTerminal}, ::Int64, ::Function, ::Function, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}, ::Vararg{NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}},N} where N) at .\strings\io.jl:89
 [6] #sprint at .\<missing>:0 [inlined]
 [7] alignment(::IOContext{Base.Terminals.TTYTerminal}, ::NamedTuple{(:a, :b),Tuple{Int64,Array{Int64,1}}}) at .\show.jl:1680
 [8] alignment(::IOContext{Base.Terminals.TTYTerminal}, ::Array{NamedTuple,1}, ::Base.OneTo{Int64}, ::Base.OneTo{Int64}, ::Int64, ::Int64, ::Int64) at .\arrayshow.jl:68
 [9] print_matrix(::IOContext{Base.Terminals.TTYTerminal}, ::Array{NamedTuple,1}, ::String, ::String, ::String, ::String, ::String, ::String, ::Int64, ::Int64) at .\arrayshow.jl:187
 [10] print_matrix at .\arrayshow.jl:160 [inlined]
 [11] print_array at .\arrayshow.jl:309 [inlined]
 [12] _display(::IOContext{Base.Terminals.TTYTerminal}, ::Array{NamedTuple,1}) at .\arrayshow.jl:345
 [13] show(::IOContext{Base.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::Array{NamedTuple,1}) at .\replutil.jl:139
 [14] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::MIME{Symbol("text/plain")}, ::Array{NamedTuple,1}) at .\repl\REPL.jl:126
 [15] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::Array{NamedTuple,1}) at .\repl\REPL.jl:129
 [16] display(::Array{NamedTuple,1}) at .\multimedia.jl:291
 [17] (::getfield(Base, Symbol("#inner#4")){Base.Iterators.IndexValue{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},typeof(display),Tuple{Array{NamedTuple,1}}})() at .\essentials.jl:666
 [18] #invokelatest#3 at .\essentials.jl:667 [inlined]
 [19] invokelatest at .\essentials.jl:666 [inlined]
 [20] print_response(::Base.Terminals.TTYTerminal, ::Any, ::Nothing, ::Bool, ::Bool, ::Nothing) at .\repl\REPL.jl:147
 [21] print_response(::Base.REPL.LineEditREPL, ::Any, ::Nothing, ::Bool, ::Bool) at .\repl\REPL.jl:133
 [22] (::getfield(Base.REPL, Symbol("#do_respond#15")){Bool,getfield(Base.REPL, Symbol("##25#35")){Base.REPL.LineEditREPL,Base.REPL.REPLHistoryProvider},Base.REPL.LineEditREPL,Base.LineEdit.Prompt})(::Base.LineEdit.MIState, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Bool) at .\repl\REPL.jl:707
 [23] top-level scope


#4

There were several similar issues, see https://github.com/JuliaLang/julia/issues/25857 and other issues referenced there. It seems that still corner cases need to be handled correctly.