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