Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you write a fun that's recursive in Erlang?

I'm trying to write a recursive fun in an Erlang shell, but I keep getting an unbound variable exception:

1> Foo = fun(X) -> Foo(X) end. * 1: variable 'Foo' is unbound 

This probably goes without saying, but I'm not trying to create an infinite loop! This is just a simple example of the error I'm getting.

like image 993
allyourcode Avatar asked May 15 '09 07:05

allyourcode


People also ask

What is fun () in Erlang?

Advertisements. Funs are used to define anonymous functions in Erlang.

What is tail recursion Erlang?

The function len(Rest) itself then needed the result of another function call to be found. The additions would get stacked until the last one is found, and only then would the final result be calculated. Tail recursion aims to eliminate this stacking of operation by reducing them as they happen.

How does recursion differ from other functions?

A recursive function generally has smaller code size whereas a non-recursive one is larger. In some situations, only a recursive function can perform a specific task, but in other situations, both a recursive function and a non-recursive one can do it.

How to implement recursion in Erlang?

Recursion is an important part of Erlang. First let’s see how we can implement simple recursion by implementing the factorial program. -module(helloworld). -export( [fac/1,start/0]). fac(N) when N == 0 -> 1; fac(N) when N > 0 -> N*fac(N-1). start() -> X = fac(4), io:fwrite("~w", [X]). The following things need to be noted about the above program −

How can I retrieve information about a fun in Erlang?

The BIFs erlang:fun_info/1,2 can be used to retrieve information about a fun, and the BIF erlang:fun_to_list/1 returns a textual representation of a fun. The check_process_code/2 BIF returns true if the process contains funs that depend on the old version of a module. The scope rules for variables that occur in funs are as follows:

How do I create a loop in Erlang?

If you want a loop, you need to create a function who call itself. Traditional while or for loop in imperative and object oriented language can be represented like that in Erlang: loop () -> % do something here loop (). Good method to understand this concept is to expand all function calls.

How to list all values stored in map in Erlang?

Map in Erlang is equivalent of hashes in Perl or dictionaries in Python, its a key/value store. To list every value stored in, you can list every key, and return key/value pair. This first loop give you an idea:


2 Answers

Since OTP 17.0 there are named funs:

1> Perms = fun F([]) -> [[]]; F(L) -> [[H|T] || H <- L, T <- F(L--[H])] end.     #Fun<erl_eval.30.54118792> 2> Perms([a,b,c]). [[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b],[c,b,a]] 

Before that you could do this with a little argument trick:

1> Foo = fun(F, X) -> F(F, X) end. #Fun<erl_eval.12.113037538> 2> Foo(Foo, a). <...infinite loop!> 

The trick here is to send in the function as an argument to itself to allow recursion.

Alternative way to make it in one shoot:

1> Foo = fun(X) -> Fun = fun(F,Y) -> F(F,Y) end, Fun(Fun,X) end. #Fun<erl_eval.6.13229925> 2> Foo(a). 

For example:

1> Foo = fun(Max) -> 1>     Fun = fun(F, X) when X > Max -> []; 1>              (F, X) -> [X | F(F, X+1)] 1>           end, 1>     Fun(Fun, 0) 1> end. #Fun<erl_eval.6.13229925> 2> Foo(10). [0,1,2,3,4,5,6,7,8,9,10] 
like image 88
6 revs, 3 users 46% Avatar answered Sep 20 '22 07:09

6 revs, 3 users 46%


After Erlang 17, you can also use the "Funs with names" variant:

Foo = fun F(X) -> F(X) end. 

In this way it is easier to understand that F is the function itself within the definition. Also, Foo and F can be the same variable.

like image 42
aronisstav Avatar answered Sep 23 '22 07:09

aronisstav