Programação funcional

Em ciência da computação, programação funcional é um paradigma de programação que trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da programação imperativa, que enfatiza mudanças no estado do programa. Enfatizando as expressões ao invés de comandos, as expressões são utilizados para cálculo de valores com wikidados imutáveis.

Uma função, neste sentido, pode ter ou não ter parâmetros e um simples valor de retorno. Os parâmetros são os valores de entrada da função, e o valor de retorno é o resultado da função. A definição de uma função descreve como a função será avaliada em termos de outras funções. Por exemplo, a função  é definida em termos de funções de exponenciação e adição. Do mesmo modo, a linguagem deve oferecer funções básicas que não requerem definições adicionais.

A programação funcional trata as funções de forma em que estas possam ser passadas como parâmetro e valores para outras e funções e podendo ter o resultado armazenado em uma constante.

Linguagens de programação funcionais, especialmente as puramente funcionais, têm sido mais usadas academicamente que no desenvolvimento comercial de software. Entretanto, algumas linguagens notáveis usadas na indústria e no comércio incluem Erlang (aplicações concorrentes), R (estatística), OCaml (quantitative trading), Mathematica (matemática simbólica) J, K (análise financeira) e XSLT. Importantes influências na programação funcional foram o cálculo lambda, as linguagens de programação APL e Lisp, e mais recentemente ML, Haskell, OCaml, F# e Elixir.

Desenvolvimento 
As funções podem ser manipuladas numa grande variedade de formas numa linguagem de programação funcional. As funções são tratadas como valores de primeira importância, o que é o mesmo que dizer que funções podem ser parâmetros ou valores de entrada para outras funções e podem ser os valores de retorno ou saída de uma função. Então podemos entender paradigma funcional como um mapeamento dos valores de entrada nos valores de retorno, através de funções. Isso permite que funções como mapcar em LISP e map em Haskell que tomam ambos uma função e uma lista como entrada e aplicam a função de entrada a cada elemento da lista. Funções podem ser nomeadas, como em outras linguagens, ou definidas anonimamente (algumas vezes durante a execução do programa) usando uma abstração lambda e usadas como valores em outras funções. Linguagens funcionais também permitem que funções sejam do tipo curry. Currying é uma técnica para reescrita de funções com múltiplos parâmetros como a composição de funções de um parâmetro. A função do tipo curry pode ser aplicada apenas a um subconjunto de seus parâmetros. O resultado é uma função onde os parâmetros neste subconjunto são agora fixados como constantes, e os valores do resto dos parâmetros ainda não são especificados. Esta nova função pode ser aplicada aos parâmetros restantes para obter o valor da função final. Por exemplo, uma função adiciona(x,y) = x + y pode ser do tipo curry de forma que o valor de retorno adiciona(2) — note que não há um parâmetro y — será uma função anônima, o que é equivalente à função adiciona2(y) = 2 + y. Esta nova função tem apenas um parâmetro e corresponde a adicionar 2 a um número. Novamente, isso é apenas possível porque as funções são tratadas como valores de primeira importância.

O cálculo lambda pode ser considerado a primeira linguagem de programação funcional, embora nunca tenha sido projetada para ser realmente executada em um computador. É um modelo de computação projetado por Alonzo Church nos anos 1930 que oferece um modo muito formal de descrever um cálculo de uma função. A primeira linguagem de programação funcional criada para computadores foi LISP, desenvolvida por John McCarthy no Instituto de Tecnologia de Massachusetts (MIT) no fim dos anos 1950. Mesmo não sendo uma linguagem de programação puramente funcional, LISP introduziu a maioria das características hoje encontradas nas modernas linguagens de programação funcional. Scheme foi uma tentativa posterior de simplificar e melhorar LISP. Nos anos 1970 a linguagem ML foi criada pela Universidade de Edimburgo, e David Turner desenvolveu a linguagem Miranda na Universidade de Kent. A linguagem Haskell foi lançada no fim dos anos 1980 numa tentativa de juntar muitas ideias na pesquisa de programação funcional.

Vantagens 
O processo de alocação de memória é automático não sendo declarado pelo usuário, eliminando os erros de alocação na função, desta maneira garantindo que a saída da função será sempre o mesmo se dado um mesmo conjunto de dados.

Desvantagens 
Na programação funcional alguns construtos básicos sobre programação, como alocamento explícito de memória ou de variáveis, são dados como inexistentes, entretanto estes construtos ainda funcionam, porém de forma menos explícita.

Linguagens de programação 
Listado abaixo algumas das principais linguagens de programação funcional:

 Prolog;
 Lisp;
 Scheme (Simplificação do Lisp);
 ML (Criação Universitária);
 Miranda (Criação Universitária);
 Haskell;
Elixir.

Exemplos

Scheme 
((lambda (x) (+ x x)) (* 3 4))Neste caso, isso é o que aconteceria:

3*4 = 12;

x = 12;

x + x = 12 + 12 = 24;.

Haskell 
dobrarLista lst = map (\x -> 2 * x) lstNeste caso em Haskell, ele mapeia uma lista chamada lst dobrando seus valores.

Contraste com a programação imperativa 
A programação funcional pode ser contrastada com a programação imperativa. Na programação funcional parecem faltar diversas construções frequentemente (embora incorretamente) consideradas essenciais em linguagens imperativas, como C ou Pascal. Por exemplo, numa programação estritamente funcional, não há alocação explícita de memória, nem declaração explícita de variáveis. No entanto, essas operações podem ocorrer automaticamente quando a função é invocada; a alocação de memória ocorre para criar espaço para os parâmetros e para o valor de retorno, e a declaração ocorre para copiar os parâmetros dentro deste espaço recém-alocado e para copiar o valor de retorno de volta para dentro da função que a chama. Ambas as operações podem ocorrer nos pontos de entrada e na saída da função, então efeitos colaterais no cálculo da função são eliminados. Ao não permitir efeitos colaterais em funções, a linguagem oferece transparência referencial. Isso assegura que o resultado da função será o mesmo para um dado conjunto de parâmetros não importando onde, ou quando, seja avaliada. Transparência referencial facilita muito ambas as tarefas de comprovar a correção do programa e automaticamente identificar computações independentes para execução paralela.

Laços, outra construção de programação imperativa, estão presentes através da construção funcional mais geral de recursividade. Funções recursivas invocam a si mesmas, permitindo que uma operação seja realizada várias vezes. Recursividade em programação funcional pode assumir várias formas e é em geral uma técnica mais poderosa que o uso de laços. Por essa razão, quase todas as linguagens imperativas também a suportam (sendo Fortran 77 e COBOL exceções notáveis).

Ver também 
 Cálculo lambda

Bibliografia 
 Cousineau, Guy and Michel Mauny. The Functional Approach to Programming. Cambridge, UK: Cambridge University Press, 1998.
 Graham, Paul. ANSI Common LISP. Englewood Cliffs, New Jersey: Prentice Hall, 1996.

 Pratt, Terrence, W. and Marvin V. Zelkowitz. Programming Languages: Design and Implementation. 3rd ed. Englewood Cliffs, New Jersey: Prentice Hall, 1996.
 Salus, Peter H. Functional and Logic Programming Languages. Vol. 4 of Handbook of Programming Languages.  Indianapolis, Indiana: Macmillan Technical Publishing, 1998.
 Thompson, Simon. Haskell: The Craft of Functional Programming. Harlow, England: Addison-Wesley Longman Limited, 1996.

 
Ciência da computação