Anonymous nested struct

Yes, a macro might be useful here. For example:

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.)

Update: PR created

14 Likes