I believe there were proposals for that, but all were turned down, as these do not really make sense in Elixir. Erlang added named lambdas for sole purpose of being able to define recursive functions in shell. This is not a problem in Elixir shell, as you can define whole module from there with ease.
However, if you really want, then you can achieve that with some black-magic macros:
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