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.
Advertisements. Funs are used to define anonymous functions in 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.
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.
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 −
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:
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.
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:
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]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With