Anonymous functions with recursion

I was playing around with lambdas. In Erlang I can do this:

3> Func = fun Func([H | T], Acc) -> Func(T, Acc + H); Func([], Acc) -> Acc  end.
#Fun<erl_eval.18.3316493>
4> Func([1,2,3,4],0).
10

Can I do the same with Elixir? This didn’t work:

iex(cs@localhost)1> func = fn func([h | t], acc) -> func(t, acc+h); func([], acc) -> acc end
** (CompileError) iex:1: undefined function func/2 (there is no such import)
    (elixir 1.14.2) src/elixir_fn.erl:17: anonymous fn/4 in :elixir_fn.expand/4
    (stdlib 4.1.1) lists.erl:1462: :lists.mapfoldl_1/3
    (elixir 1.14.2) src/elixir_fn.erl:23: :elixir_fn.expand/4
2 Likes

Afaik recursive anonymous functions are not supported in elixir. Either use a module and put recursive functions on that or use some of the Enum APIs abstracting recursion.

1 Like

Not quite, but you can do it if you bring your own Y-combinator:

iex(1)> func = fn [h | t], acc, f -> f.(t, acc+h, f); [], acc, _f -> acc end    
#Function<40.3316493/3 in :erl_eval.expr/6>

iex(2)> func.([1,2,3,4], 0, func)
10

(technique inspired by Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich - YouTube which is a must-watch if you’re playing with lambdas)

2 Likes

I think I recall that