If you feel adventurous then you can check out my small macro that I have created for this purpose:
defmodule Foo do
defmacro fn_rec(do: body) do
{name, argc, body} =
body
|> Enum.map(fn
{:'->', e1, [[{:when, e2, [{name, _, args}, guard]}], body]} ->
{name, length(args), {:'->', e1, [[{:when, e2, args ++ [guard]}], body]}}
{:'->', e1, [[{name, _, args}], body]} ->
{name, length(args), {:'->', e1, [args, body]}}
end)
|> Enum.reduce(fn {name, argc, body}, {name, argc, acc} ->
{name, argc, List.wrap(acc) ++ [body]}
end)
args = Macro.generate_arguments(argc, __CALLER__.module)
func = {:fn, [], body}
name = {name, [], Elixir}
quote do
tmp =
fn f ->
var!(unquote(name)) = fn unquote_splicing(args) -> f.(f).(unquote_splicing(args)) end
unquote(func)
end
tmp.(tmp)
end
end
def run do
ack =
fn_rec do
a(0, n) -> n + 1
a(m, 0) -> a.(m - 1, 1)
a(m, n) -> a.(m - 1, a.(m, n - 1))
end
ack.(3, 4)
end
end
IO.puts Foo.run






















