Maybe there is a reason to have something like this that I can’t immediately think of, but as far as readability goes I find your third example much more readable and aesthetically pleasing than the first.
Ah, yes, indeed NamedTuples are anonymous structs. But aesthetically, I still feel NamedTuple syntax looks a little bit cluttered than the first example. But I agree that it’s subjective and arguable.
Possible benefit of the first example is 1) fieldname and type are side by side 2) when deeply nested, it is more readable than NamedTuple:
struct ABC
name::String
data::struct
raw::Vector{Float64}
value::Int
innerFields::struct
val::Int
name::String
data::struct
arr:Array{Float64, 3}
end
end
end
end
Equivalent NamedTuple exression would be rather complex.
macro NamedTuple(ex)
Meta.isexpr(ex, :block) || error("@NamedTuple requires a begin-end block")
decls = filter(e -> !(e isa LineNumberNode), ex.args)
all(e -> Meta.isexpr(e, :(::)), decls) || error("@NamedTuple requires a block of name::type expressions")
vars = [QuoteNode(e.args[1]) for e in decls]
types = [e.args[2] for e in decls]
return :(NamedTuple{($(vars...),), Tuple{$(types...)}})
end
allows you to do:
julia> @NamedTuple begin
raw::Vector{Float64}
value::Int
end
NamedTuple{(:raw, :value),Tuple{Array{Float64,1},Int64}}
It might be reasonable to include something like this in Base, if someone wants to put together a PR.
See also allow @foo{...} macro calls · Issue #34498 · JuliaLang/julia · GitHub regarding an alternative syntax @NamedTuple{raw::Vector{Float64}, value::Int} that might be a bit nicer. (Of course, a single macro could easily support both {...} and begin ... end syntaxes, just by using Meta.isexpr(ex, :block) || Meta.isexpr(ex, :brace) on the first line.)
julia> @NamedTuple begin
raw::Vector{Float64}
value::Int
data::@NamedTuple begin
arr::Vector{Float64};
end
end
NamedTuple{(:raw, :value, :data),Tuple{Array{Float64,1},Int64,NamedTuple{(:arr,),Tuple{Array{Float64,1}}}}}
It works! why didn’t it work yesterday? I ran the code on a computer with Julia 1.1.1 installed. Now I run it on Julia 1.3 and confirm it works. I am staring at your code to understand it. Its should go to Base.