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.

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