Recursive anonymous functions

1> G = fun                  
1>   F (0, Acc) -> Acc;        
1>   F (Num, Acc) -> F(Num - 1, Acc + 1)
1> end.
#Fun<erl_eval.36.128620087>
2> G(10,10).
20
3>

Even though this feature now exists in Erlang the points are:

  1. There already is a solution in Elixir (and Erlang pre-17.0) that works even if it isn’t elegant.
  2. How often does a real need for recursive anonymous functions actually come up, given that recursion is well supported with named functions within actual code (rather than the shell)?

Erlang and by extension Elixir are pragmatic languages.

I contend that anonymous functions are an overused feature which are even more prevalent in Elixir because of the existence of the shorthand notation.

I see the primary value of an anonymous function in it’s closure (i.e. its connection to the scope that created it) - that should be the reason for using it. More often than not they are used simply for notational convenience even though quite often code becomes less readable.

The Erlang named anonymous function example can be quite easily emulated with a mixture of an anonymous function for its closure and a named function to do the real work:

# file: Demo.ex
# Original: https://learnyousomeerlang.com/higher-order-functions#highlighter_833032
#
defmodule Demo do
  def prepare_alarm(room) do
    IO.puts("Alarm set in #{room}")
    fn -> loop(room) end
  end

  defp loop(room) do
    IO.puts("Alarm tripped in #{room}! Call Batman!")
    Process.sleep(500)
    loop(room)
  end
end
iex(1)> c("Demo.ex")
[Demo]
iex(2)>  alarm_ready = Demo.prepare_alarm("bathroom")
Alarm set in bathroom
#Function<0.61175415/0 in Demo.prepare_alarm/1>
iex(3)>  alarm_ready.()
Alarm tripped in bathroom! Call Batman!
Alarm tripped in bathroom! Call Batman!
Alarm tripped in bathroom! Call Batman!

BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
a
2 Likes