-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: NamedTuple macro for easier type construction #34548
Conversation
Might be even better to just have real syntax for this... |
I don't think we would want (I suppose that |
🤷♂ maybe the macro syntax is for the best. |
Is it too evil to use |
Co-Authored-By: Takafumi Arakaki <aka.tkf@gmail.com>
I vote for too evil, at least for now. We can reconsider later. |
Re #34548 (comment) I'm seeing the effect of julia> module Demo1
macro NamedTuple(ex)
Meta.isexpr(ex, :braces) || Meta.isexpr(ex, :block) ||
throw(ArgumentError("@NamedTuple expects {...} or begin...end"))
decls = filter(e -> !(e isa LineNumberNode), ex.args)
all(e -> e isa Symbol || Meta.isexpr(e, :(::)), decls) ||
throw(ArgumentError("@NamedTuple must contain a sequence of name or name::type expressions"))
vars = [QuoteNode(e isa Symbol ? e : e.args[1]) for e in decls]
types = [esc(e isa Symbol ? :Any : e.args[2]) for e in decls]
return :(NamedTuple{($(vars...),), Tuple{$(types...)}})
end
end # module Demo1
Main.Demo1
julia> module Demo2
macro NamedTuple(ex)
Meta.isexpr(ex, :braces) || Meta.isexpr(ex, :block) ||
throw(ArgumentError("@NamedTuple expects {...} or begin...end"))
decls = filter(e -> !(e isa LineNumberNode), ex.args)
all(e -> e isa Symbol || Meta.isexpr(e, :(::)), decls) ||
throw(ArgumentError("@NamedTuple must contain a sequence of name or name::type expressions"))
vars = [QuoteNode(e isa Symbol ? e : e.args[1]) for e in decls]
types = [e isa Symbol ? :Any : e.args[2] for e in decls]
return :(NamedTuple{($(vars...),), Tuple{$(types...)}})
end
end # module Demo2
Main.Demo2
julia> struct Foo end
julia> Demo1.@NamedTuple{a::Foo}
NamedTuple{(:a,),Tuple{Foo}}
julia> Demo2.@NamedTuple{a::Foo}
ERROR: UndefVarError: Foo not defined
...
julia> @macroexpand Demo1.@NamedTuple {a::Foo}
:(Main.Demo1.NamedTuple{(:a,), Main.Demo1.Tuple{Foo}})
julia> @macroexpand Demo2.@NamedTuple {a::Foo}
:(Main.Demo2.NamedTuple{(:a,), Main.Demo2.Tuple{Main.Demo2.Foo}}) Maybe this'd be a nice test case? |
win32 test failures seem unrelated (failure in cmdlineargs and downloading curl). |
👍 from triage. |
Following #34498, #34505, and a recent discourse discussion, this PR defines (and exports) a macro
@NamedTuple
that provides a more convenientstruct
-like syntax for definingNamedTuple
types:If a
::Type
is not specified, it is treated as::Any
(similar to astruct
).This will only be useful if #34547 is resolved, however. (Alternatively, the PR could be changed to require a type specifier for all keys.)Abstractly typed fields ofNamedTuple
work fine.