Paradigma Funcional

O Paradigma funcional consiste em desenvolver funções que solucionam um determinado problema. Tais funções obedecem aos príncipios matemáticos, embora nem sempre podem ser consideradas funções totais.
Uma função é dita total quando todo elemento de um conjunto A tem um representante em um conjunto B. Normalmente, todos os cálculos matemáticos levam em contam funções totais por serem de menor complexidade que as funções parciais.
Ao contrário do Paradigma Imperativo que trata estados e eventos provocados em um sistema, o Paradigma Funcional trabalha de forma avaliativa, assim como as calculadoras, lê uma expressão, calcula o seu valor e apresenta o resultado.

A característica predominante da programação funcional é que o significado de um expressão é o seu valor, e o papel do computador é obtê-lo. Nas linguagens funcionais as funções são entidades de 1ª Classe, i.e., podem ser usadas como parâmetros, retornadas como resultado e até mesmo armazenadas em estruturas.

As linguagens funcionais são naturalmente recursivas e implementam de forma mais rápida o conceito de recursão. Este fato dependendo do contexto podem torná-las mais eficientes que as linguagens imperativas para alguns problemas.

Nota: Pode-se encontrar neste link uma comparação mostrando que Haskell pode ser mais eficiente que C para processadores com vários núcleos.
Algumas características
  • as expressões são a representação exata da informação;
  • as expressões podem ser associadas a nomes;
  • todos os nomes que em uma expressão tem um valor único e imutável;
  • os valores dependem dos valores das sub-expressões que as constituem;
  • não permite efeito colateral em funções, a linguagem oferece transparência referencial.
Vantagens
  • mais eficiente que as liguangens imperativas para cálculo recursivo;
  • transparência referencial;
  • grande flexibilidade, capacidade de abstração e modularização.
Desvantagens
  • ilegibilidade do código;
  • os programas podem ser menos eficiente.
Principais linguagens
  • Lisp
  • ML
  • Miranda
  • Haskell
Conclusão

Todo paradigma de programação, assim como tudo existente, tem seus prós e contras e o paradigma funcional não foge a essa regra. Pode-se considerar alguns contextos que as linguagens funcionais podem e devem ser utilizados, como: cálculos matemáticos e recursivos. Para as situações comumente encontradas nos ambientes de desenvolvimento é preferível usar paradigmas de mais clara legibilidade.

Referências
José Mauro da Silva Sandy

Clube de Revista
  • Anterior - Programação Estruturada versus Programação Orientada a Objetos
  • Próxima - ?

9 comentários:

  Lopes

1 de março de 2009 às 04:37

Salve, salve!

Retomando o CR...

Gostei do post; bastante explicativo. Eu sempre achei o paradigma funcional muito difícil de entender e concordo plenamente sobre a legibilidade do código, que fica muito ruim neste paradigma. Parece até que os desenvolvedores de Python, na versão 3.0, não deram tanta atenção para a parte funcional da linguagem.

Só senti falta no texto de algo mais prático. Um trecho de código funcional, para demonstrar o funcionamento. Pode postar um exemplo do tipo?

Só um detalhe, pra terminar: você colocou uma foto de lambda para ilustrar o texto, mas não deixou claro a ligação dela com o conteúdo...

Detalhes...

[]!

  José Mauro

1 de março de 2009 às 12:25

Fala ae Zé!

Vamos as respostas.

1º) "...senti falta no texto de algo mais prático...."

Um exemplo funcional em Python, que acredito ser bem legal, pode fazer uso da função reduce.

Você já deve saber mais a função reduce recebe como entrada uma função com dois valores e uma sequência que será será calculada. Pode-se ter um terceiro argumento opcional que é um inicializador. Retorna a soma de todos os itens da sequência.

Sintaticamente, tem-se:

reduce(função, sequência, [inicializador])

Exemplo: Este código calcula todos os termos de um sequência númerica, pode-se usá-la, e.g., em um software matemático para cálculo da Soma de Termos de uma progressão.

reduce(lambda x, y: x + y, [3, 7, 11, 15, 19])

Ao ser executado retorna o valor da soma dos elementos da lista.

2º) "...você colocou uma foto de lambda para ilustrar o texto, mas não deixou claro a ligação dela com o conteúdo..."

O paradigma funcional se baseia no cálculo lambda em que valores podem ser calculados e retornados para cálculo em outras funções.E como é conhecido o paradigma funcional utiliza-se intensamente de chamadas recursivas e chamadas em cascata para retorna de resultados.

[]s

  Lopes

1 de março de 2009 às 21:54

Nesse exemplo que você citou do reduce() com o lambda, você sabe me explicar o que o lambda devolve para o reduce()?

Aproveitando, eu me deparei com um trecho de código em Python semelhante a esse:

>>> lambda d, r: d.function()

Você sabe explicar o que ocorre ali? Por que tem uma chamada pra r, sendo que ele não é usado?

Inté!

  José Mauro

2 de março de 2009 às 23:16

Fala!!!

Desculpa a demora é que eu não pude responder antes. A função lambda retorna uma soma de entre dois valores que são fornecidos pela função reduce.

A função reduce, vai passando os elementos da lista até que a mesma acabe. Por exemplo, recebimento de lambda:
1° 3 + 7; retorno 10
2° 10 + 11; retorno 21

Até percorrer e chegar a um número somente.

Kra, imagino que seja o seguinte como na programação funcional a idéia e devolver valores entre funções, todas as funções tem acesso aos valores das funções envolventes. Neste caso o argumento r, para não me servir pra muita coisa. Mas o valor passado em d, talvez um objeto, faça chamada a algum método e este método retorna o valor a essa função. Acredito que seja isso.

Abraço.

  Lopes

4 de março de 2009 às 13:45

Só pra finalizar, eu creio que a programação funcional é uma grande aliada para programadores. Bom, na verdade, qualquer conhecimento a mais é aliado. Algumas vezes é mais fácil usar while, outras for, mas qualquer uma das duas poderia implementar uma iteração.

Como citado, a programação funcional tem vantagens e desvantagens. Cabe a cada programador, no meu ponto de vista, pesar se vale a pena ou não utilizá-la. Se vale a pena abrir mão da legibilidade em determinada parte do código (em caso de estar usando Python), para prover uma solução com menos linhas e TALVEZ melhor desempenho, mesmo que signifique um ganho de 1ms.

É isso!
Inté!

  José Mauro

5 de março de 2009 às 09:11

Concordo plenamente com você que todo conhecimento agregado é um auxílio ao programador.

O mais interessante é que sempre fica a critério do desenvolvedor, na maioria das vezes e claro, escolher o melhor.

Abraço.

  Lopes

11 de março de 2009 às 13:31

Acabei de ler uma colocação bastante interessante do Luciano Ramalho sobre o Lambda, na lista do PythonBrasil. Segue a mensagem na íntegra:

> Lambda[1] sempre é bonito:
>
> funcao = lambda a,x0,x: 1./(1.+exp(-a*(x-x0))
> funcao(1,2,3)
>
> [1] http://docs.python.org/tutorial/controlflow.html#lambda-forms

Eu não acho que lambda seja "sempre" bonito. No seu exemplo, esta
fórmula deve ter um nome certo? Não seria ter uma função com o nome da
fórmula?

Às vezes usar lambda fica bom, em casos bem específicos e simples.
Fora isso, acho melhor definir uma função com um nome bem descritivo.
A principal característica do lambda, que é criar funções anônimas, é
também em muitos casos usos o principal defeito: fica faltando um nome
para descrever a intenção.

Gostei do procedimento para refatorar lambdas do Fredrik Lundh, citado
pelo A.M. Kuchling em seu "Functional Programming HOW-TO" [2]. As
regras são:

1. Escreva uma função lambda
2. Escreva um comentário explicando que diabos aquela lambda faz
3. Estude o comentário por algum tempo, e pense num nome que capture a
essência do comentário
4. Converta o lambda para um def, usando aquele nome
5. Remova o comentário

[2] http://docs.python.org/dev/howto/functional.html

[ ]s
Luciano

  Fernando Sanches

3 de maio de 2009 às 20:11

Acho legal a divulgação do paradigma funcional, é algo meio "underground" mas que promete se tornar bem mais importante em breve.

Apenas umas críticas ao post:
Ilegibilidade de código é algo muito relativo. Recentemente eu gastei 2 horas caçando um bug de 1 linha em um código de Java, já que a ração barulho/código significativo era muito grande
Sim, ler 5 linhas de código funcional é mais difícil que ler 5 linhas de código imperativo, mas isso porque o código funcional costuma ser muito mais denso e expressivo.

Tem gente que prefere ver uma idéia detalhada em 50 linhas, eu prefiro vê-la condensada a 5 linhas.

E Haskell é muito mais legível que Perl, por exemplo. Scheme, apesar de ter uma certa poluição de parênteses, possui uma sintaxe claríssima.

E, sem exemplos claros, não dá pra levar esse seu levantamento à sério.

Quanto à referência transparencial, ela não é exatamente uma característica do paradigma, mas sim da linguagem. ML, Scala e F# (dentre tantas outras) não a possuem mas mesmo assim são consideradas funcionais.

  Anônimo

9 de agosto de 2011 às 13:38

Informacao super clara, nao ha como nao perceber o conceito de paradigma funcional. adorei...