Having fun with Funs!
When I started with Erlang, a lot of people told me one of its strenghts was the fact that it is a functional language. Coming from Java, for me this was one of the most difficult things to tackle, and only after a good series of books and blogs I started understanding the concept.
Here follows the the code to implement a function that takes a value as input and doubles it:
1> Double = fun(Value) -> Value * 2 end. #Fun<erl_eval.6.13229925> 2> Double(2). 4 3> Double(4). 8
Above I defined a function by using the sintax fun(Params) -> … end, you may notice that the function is bound to the variable Double, this allows you to reuse this function any time you need just by calling Double(Value).
As suggested in Erlang Programming by Cesarini and Thompson, you can use also this notation:
4> (fun(Value) -> Value * 2 end)(3). 6
but this way, you may not be able to reuse it several times.
The two examples above were written using anonymous functions notation: fun() -> end. This kind of function can do everything
normal functions do, exept calling themselves recursively.
Working with Erlang, bring you to deal with lists: usually this simply means that you need to cross the list and apply a certain function to all its items.
You can abstract this situation by using a map function; map takes two arguments as input: a first one that represents the function we want to apply to each element of the list, and a second one that is the list itself:
map(Fun, ) -> ; map(Fun, [H|T]) -> [Fun(H) | map(Fun, T)].
What did we do with the code above? Well, basically we told that the function map takes two arguments (notice that there is no
difference when they are list or function), if the second argument is an empty list we just return an empty list, while if the input is a not-empty list, we return a list made by the result of the function applied to the first element, and the result of the map function applied to the rest of the list.
To be honest, you don’t have to declare you own map function, because it already exists in the module lists (I strongly suggest you to take a look at it):
11> A = [1,2,3,4,5]. 12> lists:map(Double, A). [2,4,6,8,10]
Of course you could also write something like:
13> lists:map(fun(Value) -> Value * 2 end, A). [2,4,6,8,10]
to get the same result.
Functional programming means also that a function can return as result another function! Let’s see how:
1> Double = fun(Value) -> io:format("You want to double:~p~n", [Value]), 1> fun() -> Value * 2 end end. #Fun<erl_eval.6.13229925> 2> Four = Double(2). you want to double:2 #Fun<erl_eval.20.67289768> 3> Four(). 4
The example above is really stupid, but still it makes you understand how you can return a function from another function.
We changed our function so that it prints on screen the number we want to double, then we return a function that actually doubles that number. In the line number two of the erlang console we bound the variable Four to the result of the function Double(2), in this way by calling Four() we can get as expected the value 4.
This is all for today! Have fun!