La recursividad se puede explicar con la ayuda de conceptos y funciones matemáticas. Una función matemática básica como el factorial de un valor es un buen ejemplo de una función que se puede expresar de forma recursiva. El factorial de un número n es el producto de la secuencia 1 x 2 x 3 x ... x n, o alternativamente n x (n-1) x (n-2) x ... x 1. Para dar algunos ejemplos, el factorial de 3 es 3! = 3 x 2 x 1 = 6. ¡El factorial de 4 sería 4! = 4 x 3 x 2 x 1 = 24. Dicha función se puede expresar de la siguiente manera en notación matemática:
Lo que esto nos dice es que si el valor de n que tenemos es 0, devolvemos el resultado 1. Para cualquier valor superior a 0, devolvemos n multiplicado por el factorial de n-1, que se desarrolla hasta llegar a 1:
4! = 4 x 3!
4! = 4x3x2!
4! = 4x3x2x1!
4! = 4 x 3 x 2 x 1 x 1
¿Cómo se puede traducir una función así de la notación matemática a Erlang? La conversión es bastante simple. Eche un vistazo a las partes de la notación: n!, 1 y n((n-1)!) y luego los ifs. Lo que tenemos aquí es un nombre de función (n!), guardias (los if) y el cuerpo de la función (1 y n((n-1)!)). ¡Cambiaremos el nombre de n! a fac(N) para restringir un poco nuestra sintaxis y luego obtenemos lo siguiente:
-module(recursive).
-export([fac/1]).
fac(N) when N == 0 -> 1;
fac(N) when N > 0 -> N*fac(N-1).
¡Y esta función factorial ya está hecha! En realidad, es bastante similar a la definición matemática. Con la ayuda de la coincidencia de patrones, podemos acortar un poco la definición:
fac(0) -> 1;
fac(N) when N > 0 -> N*fac(N-1).
Una definición de recursividad podría abreviarse diciendo "una función que se llama a sí misma". Sin embargo, necesitamos tener una condición de parada (el término real es el caso base), porque de lo contrario haríamos un bucle infinito. En nuestro caso, la condición de detención es cuando n es igual a 0. En ese momento ya no le decimos a nuestra función que se llame a sí misma y detiene su ejecución allí mismo.