refer this post: How to create a dynamic function name using Elixir macro?.
The post above asked how to use macro to generate function without arguments, but I wonder how to generate functions with some arguments ?
assume there is a macro warp
, I could just write code like:
warp fun, [args], :ok
and then it generate code like:
fun(args), do: :ok
Arity means how many input parameters Elixir function has. This post is part of the functional language series, and it is based on the remarkable book Elixir In Action by Sasa Juric. In Elixir, function uniqueness is defined with: Module name.05-Jun-2020.
Macros are compile-time constructs that are invoked with Elixir's AST as input and a superset of Elixir's AST as output. The macro receives the representation of the code given as argument, while a function receives the result of the code given as argument. A macro must return a superset of the code representation.
Elixir already provides mechanisms to write your everyday code in a simple and readable fashion by using its data structures and functions. Macros should only be used as a last resort. Remember that explicit is better than implicit. Clear code is better than concise code.
If you want to generate a dynamic list of arguments, you need to use unquote_splicing
, like this:
defmacro warp(name, argument_names, code) do
quote do
def unquote(name)(unquote_splicing(argument_names)) do
unquote(code)
end
end
end
Then later:
warp :foo, [a, b], {:ok, a, b}
which generates:
def foo(a, b), do: {:ok, a, b}
if you call that it will produce:
foo(1, 2)
# {:ok, 1, 2}
You can also define the macro like this without unquote_splicing
and just pass down the combined name and arguments to def
:
defmacro warp(name_and_args, do: code) do
quote do
def unquote(name_and_args) do
unquote(code)
end
end
end
This means you need to invoke warp
like you would invoke def
, for example:
warp foo(a, b), do: {:ok, a, b}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With