How to define recursive anonymous function in Elixir?

How can I define the recursive anonymous function in Elixir? In Erlang, I can write:

1> F = fun X([]) -> []; X([H|T]) -> [H+1|X(T)] end.
#Fun<erl_eval.20.79398840>
2> F([5,41,13]).
[6,42,14]

I can’t find in documentation a way how to write a similar function in Elixir.

Afaik this is not supported in elixir.

So we are stick with this half Y-combinator solution? What a shame

iex(9)> f = fn l -> g = fn [], _ -> []; [h|t], f -> [h+1|f.(t,f)] end; g.(l,g) end
#Function<44.79398840/1 in :erl_eval.expr/5>
iex(10)> f.([3,41,5])                                                              
[4, 42, 6]

It’s like going ten years backwards when we have to do this in Erlang.

1 Like

In elixir, unlike in Erlang, you can define modules in the shell. So when you do need to write a recursive function you can do

iex> defmodule Rec do
...>   def recurse([]), do: []
...>   def recurse([h | t]), do: [h + 1 | recurse(t)] 
...> end
2 Likes

Yes, you solved this trivial example but what if I would like to make function which returns recursive anonymous function with nontrivial closure. For example returning ad hoc enumerate protocol implementation.

I’m not sure I follow honestly. Could you give a more realistic example of what you’re trying to do if the above was too trivial?

4 Likes
f = fn
  ([], _fun) ->
    []
  ([h | t], fun) ->
    [h+1 | fun.(t, fun)]
  end

f.([1, 2, 3], f)
3 Likes

Previous thread: Recursive anonymous functions

2 Likes