Tail recursion
In functional programming languages you don't write loops, you write tail recursion instead. Let's see how you implement factorial in Erlang (everybody like to implement factorial!):
-module(world).
-export([start/0]).
start() ->
io:format("~p~n", [factorial(10)]).
factorial(1) -> 1;
factorial(Number) ->
Number * factorial(Number - 1).
We call this type of recursion tail because recursive call is the latest statement of the function. Since there's nothing else after the recursive call, compiler can discard the current stack frame before the call, but not after as you may expect. That's why tail recursion depth isn't limited by the stack size and can continue infinitely. And that's how you write loops in functional programming.
In the example above we implemented factorial
function for two different cases: when the arguments equals to one, and when the argument has some other value.
Note that we end the first case with a semicolon, and the last case with a dot. In fact, you should end every case but the last with a semicolon, and the latest with a dot.
You may think that this is a function overloading, like you do in C++. However it's not really. In Erlang you have to provide all function cases in a single sequence. Once you've put a dot — the function is completed. You cannot define another case for this function somewhere later like you can do in C++.
Allright, let's build and run it:
> run.sh
> erlc world.erl
> erl.exe -noshell -s world start
3628800
3628800 is what 10! equals to. Whew, it works!