Is there a way to use a macro like
default_v = 1
af = @anonymous_func begin
@show v
end v=default_v
to get transformed into
(;v=1) -> @show v
I am wondering whether this is possible as the macro is created before default_v
is known, right?
As a step into the right direction though I would be happy to transform
af = @anonymous_func begin
@show v
end v=1
into the anonymous function shown above. I am having difficulties parsing the expr...
as something using as the keyword arguments like:
macro anonymous_func(body::Expr, expr...)
expr = quote
(;$expr) -> begin eval($body) end
end
esc(expr)
doesn’t work.
It’s not very elegant, but you can mess around with the Expr
objects directly:
julia> :((;a=1) -> a) |> dump
Expr
head: Symbol ->
args: Array{Any}((2,))
1: Expr
head: Symbol tuple
args: Array{Any}((1,))
1: Expr
head: Symbol parameters
args: Array{Any}((1,))
1: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol a
2: Int64 1
2: Expr
head: Symbol block
args: Array{Any}((2,))
1: LineNumberNode
line: Int64 1
file: Symbol REPL[338]
2: Symbol a
So something like this:
macro anonymous_func(body::Expr, expr...)
leftside = Expr(:tuple, Expr(:parameters, [Expr(:kw, e.args[1], e.args[2]) for e in expr]...))
out = Expr(:(->), leftside, body)
esc(out)
end
julia> foo = @anonymous_func begin
v + w
end v = 10 w = 1
#427 (generic function with 1 method)
julia> foo()
11
julia> foo(v = 2, w = 3)
5
Obviously that macro needs a lot more safety checking and attention overall… but it can get the job done.
3 Likes
Thanks a lot always learning new stuff here