Reputation: 2115
some_dynamic_atom = :"prefix_#{name}"
quote do
Task.Supervisor.async_nolink(Tasks.Chain, &unquote(some_dynamic_atom)/0)
end
# Should become
Task.Supervisor.async_nolink(Tasks.Chain, &prefix_smth/0)
I need to create a dynamic function in Elixir macro and pass its name to the Task
I made a dynamic function, however the macro above gives me an error:
invalid args for &, expected an expression in the format of &Mod.fun/arity, &local/arity or a capture containing at least one argument as &1, got: :prefix_smth / 0
One possible solution is to use fn -> unquote(some_dynamic_atom)() end
, but my benchmarks show, that using an anonymous wrapper noticeably slows down the execution.
Upvotes: 0
Views: 648
Reputation: 51349
If you write &unquote(some_dynamic_atom)/0
, you are generating &:some_dynamic_atom/0
, which is not what you want. Instead you want this: &some_dynamic_atom/0
. You can convert the atom to the AST of a variable using Macro.var
:
&unquote(Macro.var(some_dynamic_atom, Elixir))/0
One possible solution is to use fn -> unquote(some_dynamic_atom)() end, but my benchmarks show, that using an anonymous wrapper noticeably slows down the execution.
How and what are you benchmarking? If some_dynamic_atom()
does nothing and you are measuring just the wrapper then the wrapper will definitely slow down. But in actual code that is invoked by the Task.Supervisor it won't matter.
Upvotes: 3