Programação Funcional – Parte II – Funções
25 Abril, 2008
No último post (que ficou meio incompleto, confesso), comecei a falar um pouco sobre o paradigma da programação funcional.
Uma das coisas citadas é o fato de o programa ser tratado como um conjunto de funções matemáticas. O que isso quer dizer?
Para visualizar isso, vamos ao clássico exemplo do fatorial.
Matematicamente falando, n! (n fatorial) é o produto de todos os números menores ou iguais a n. Ou seja, o produto entre todos os números de 1 até n. Por exemplo: 5! = 1 * 2 * 3 * 4 * 5.
Observe que 0! = 1 já que o resultado de não se multiplicar nenhum número (identidade multiplicativa) é 1 (mais informações em http://en.wikipedia.org/wiki/Empty_product).
Normalmente existem 2 formas de se fazer isso: recursiva e interativa:
Recursiva:
int fatorial(int n)
{
if(n <= 1)
return 1;
return n * fatorial(n - 1);
}
Interativa:
int fatorial(int n)
{
int r = 1;
while(n > 1)
r *= n--;
return r;
}
Isso em uma linguagem funcional (no caso, Haskell), ficaria como:
fatorial :: Int -> Int
fatorial 0 = 1
fatorial n = n * fatorial (n - 1)
Muito parecido com a versão recursiva em linguagens não-funcionais.
E, de fato, muito do que se faz em uma linguagem funcional é recursivo.
Porém, uma linguagem funcional normalmente oferece vários “artifícios matemáticos” para se trabalhar.
Em Haskell, por exemplo, isso poderia ser escrito como
fatorial :: Int -> Int
fatorial n = product [1..n]
ou seja, literalmente o que diz a definição: o produto entre todos os números de 1 até n.
Uma das principais vantagens disso é a redução da quantidade de código. Considerando que a declaração do tipo não é necessáriamente obrigatória (apesar de uma boa prática) a função pode ser implementada em apenas uma ou duas linhas, respeitando os padrões de identação e tudo mais.