Mas isso vai mudar em breve. Mais e mais conceitos de FP estão sendo integrados em linguagens como Java e Python . E linguagens mais modernas, como Haskell, são totalmente funcionais. Para colocar a programação funcional em termos simples

, então esta é a criação de funções para trabalhar com variáveis imutáveis. Em contraste, a programação orientada a objetos é quando um conjunto relativamente constante de funções é usado, e o programador está ocupado principalmente modificando variáveis existentes e criando novas.
O FP, por sua natureza, é adequado para resolver problemas urgentes, como análise de dados e aprendizado de máquina . Isso não significa que você precisa dizer adeus à programação orientada a objetos e mudar completamente para a programação funcional. É simplesmente útil para o programador moderno conhecer os princípios básicos do FP, o que o capacitará a aplicar esses princípios onde eles podem servi-lo bem.
A programação funcional trata da eliminação dos efeitos colaterais
Para entender os princípios da programação funcional, primeiro você precisa entender o que é uma "função". Pode parecer enfadonho, mas no final permitirá que você veja o que à primeira vista é imperceptível. Então, vamos falar sobre funções.
Uma função, em termos simples, é uma entidade que converte alguma entrada passada a ela em dados de saída que ela retorna ao local da chamada. É verdade que nem sempre tudo parece tão simples. Dê uma olhada na seguinte função Python:
def square(x):
return x*x
Esta função é extremamente simples. Leva um argumento,
x
que provavelmente é do tipo int
, e talvez do tipo float
ou double
, e retorna o resultado da x
quadratura disso.
E aqui está outra função:
global_list = []
def append_to_list(x):
global_list.append(x)
À primeira vista, parece que aceita
x
algum tipo e não retorna nada, já que não há expressão nele return
. Mas não vamos tirar conclusões precipitadas!
A função não pode funcionar normalmente se a variável não for declarada antecipadamente
global_list
. O resultado desta função é uma lista modificada armazenada em global_list
. Mesmo que não seja global_list
declarada como um valor que é passado para a entrada de uma função, essa variável muda depois que a função é chamada.
append_to_list(1)
append_to_list(2)
global_list
Depois de algumas chamadas para a função do exemplo anterior, não
global_list
haverá mais uma lista vazia, mas uma lista [1,2]
. Isso nos permite dizer que a lista, na verdade, é o valor fornecido à entrada da função, embora isso não seja corrigido de forma alguma quando a função for declarada. Isto pode ser um problema.
Desonestidade ao declarar funções
Esses valores implícitos de entrada ou saída têm um nome oficial: efeitos colaterais. Estamos usando exemplos muito simples aqui, mas em programas mais complexos, os efeitos colaterais podem levar a complicações reais .
Pense em como você testaria a função
append_to_list
. Não será suficiente ler a primeira linha de sua declaração e descobrir que ela precisa ser testada passando algum valor x
. Em vez disso, você precisará ler todo o código da função, descobrir o que exatamente está acontecendo lá, declarar uma variável global_list
e, em seguida, testar a função. O que em nosso exemplo simples, ao que parece, não causa nenhuma dificuldade especial, em programas compostos por milhares de linhas de código, será completamente diferente.
Felizmente, o problema acima é fácil de resolver. Você só precisa ser honesto ao especificar o que exatamente deve ir para a entrada da função. A próxima versão de nossa função parece muito melhor do que a anterior:
newlist = []
def append_to_list2(x, some_list):
some_list.append(x)
append_to_list2(1,newlist)
append_to_list2(2,newlist)
newlist
Não mudamos muito neste código. Como resultado, a função in
newlist
, como antes global_list
, é exibida [1,2]
e todo o resto parece o mesmo de antes.
No entanto, fizemos uma alteração significativa neste código. Nós nos livramos dos efeitos colaterais. E isso é muito bom.
Ou seja, agora, depois de ler a primeira linha da declaração da função, sabemos exatamente com quais dados de entrada ela trabalha. Como resultado, se o programa não se comportar conforme o esperado, você pode testar facilmente todas as funções que ele contém e encontrar aquela que não está funcionando corretamente. Funções puras são mais fáceis de manter.
Programação funcional é escrever funções puras
Uma função que, quando declarada, indica claramente o que é necessário e o que retorna é uma função sem efeitos colaterais. Uma função sem efeitos colaterais é uma função pura.
Aqui está uma definição muito simples de programação funcional. Isso é escrever programas que consistem apenas em funções puras. Funções puras nunca modificam os dados passados a eles, apenas criam novos e os retornam. (Observe que trapaceei um pouco no exemplo anterior. Está escrito no espírito da programação funcional, mas nele a função modifica a lista de variáveis globais. Mas aqui estamos apenas examinando os princípios básicos do FP, e é por isso que fiz exatamente isso. Se quiser, aqui você pode encontre exemplos mais rigorosos de funções puras.)
Além disso, ao trabalhar com funções puras, você pode esperar que elas, recebendo os mesmos dados como entrada, sempre formem a mesma saída. E funções que não são puras podem depender de algum tipo de variáveis globais. Como resultado, eles, recebendo a mesma entrada, podem produzir resultados diferentes, dependendo do valor das variáveis globais. Esse fato pode complicar significativamente a depuração e manutenção do código.
Existe uma regra simples para detectar efeitos colaterais. Já que ao declarar funções puras, deve ser definido claramente o que elas recebem como entrada e retorno, funções que não aceitam ou retornam nada não serão limpas. Se você decidir incorporar técnicas de programação funcional em seu projeto, a primeira coisa que provavelmente desejará fazer é verificar suas declarações de função.
O que programação funcional não é
▍ Mapear e reduzir funções
Loops são mecanismos que não estão relacionados à programação funcional. Dê uma olhada nos seguintes loops Python:
integers = [1,2,3,4,5,6]
odd_ints = []
squared_odds = []
total = 0
for i in integers:
if i%2 ==1
odd_ints.append(i)
for i in odd_ints:
squared_odds.append(i*i)
for i in squared_odds:
total += i
Com a ajuda deste código, resolvemos problemas simples, mas acabou por ser bastante longo. E, além disso, não é funcional, uma vez que as variáveis globais são modificadas aqui.
E agora - outra versão deste código:
from functools import reduce
integers = [1,2,3,4,5,6]
odd_ints = filter(lambda n: n % 2 == 1, integers)
squared_odds = map(lambda n: n * n, odd_ints)
total = reduce(lambda acc, n: acc + n, squared_odds)
Este é um código totalmente funcional. É mais curto. É mais rápido porque você não precisa iterar em muitos elementos do array. E, se você entender as funções
filter
, map
e reduce
, verifica-se que esse código não é muito mais difícil de entender do que aquele em que os loops são usados.
Isso não significa que em qualquer código de função seja usado
map
, reduce
e outras funções semelhantes. E isso não significa que, para lidar com tais funções, você precise conhecer programação funcional. A questão é que essas funções são freqüentemente usadas ao se livrar de loops.
▍ Funções de Lambda
Quando as pessoas falam sobre a história da programação funcional, geralmente começam falando sobre a invenção das funções lambda. Mas embora as funções lambda sejam, sem dúvida, a pedra angular da programação funcional, elas não são a principal causa do FP.
As funções lambda são ferramentas que podem ser usadas para escrever programas em um estilo funcional. Mas essas funções também podem ser usadas na programação orientada a objetos.
▍ Digitação estática
O exemplo acima não é digitado estaticamente. Mesmo assim, é um exemplo de código funcional.
Mesmo que a tipagem estática acrescente uma camada extra de segurança ao seu código, não é um requisito para a criação de código funcional. Pode, entretanto, ser uma boa adição ao estilo de programação funcional.
Deve-se notar que algumas linguagens são mais fáceis de programar em um estilo funcional do que outras.
Algumas linguagens são "mais funcionais" do que outras
▍Perl
Perl tem uma abordagem para lidar com os efeitos colaterais que o diferencia da maioria das outras linguagens. Ou seja, tem uma "variável mágica"
$_
que traz os efeitos colaterais ao nível de uma das principais características da linguagem. Perl tem seus méritos, mas eu não tentaria fazer programação funcional nesta linguagem.
▍Java
Desejo a você boa sorte ao escrever código Java funcional. Não vai te machucar. Primeiro, a palavra-chave ocupará metade do código
static
. Em segundo lugar, a maioria dos programadores Java chamará seu código de mal-entendido.
Isso não significa que Java seja uma linguagem ruim. Mas não foi projetado para resolver o tipo de problema para o qual a programação funcional é excelente. Por exemplo - para gerenciamento de banco de dados ou para o desenvolvimento de aplicativos da área de aprendizado de máquina.
▍Scala
Scala é uma linguagem interessante. Seu objetivo é unificar a programação funcional e orientada a objetos. Se isso lhe parece estranho, saiba que não está sozinho. Afinal, a programação funcional visa eliminar completamente os efeitos colaterais. A programação orientada a objetos trata de limitar os efeitos colaterais aos objetos.
Com isso em mente, podemos dizer que muitos desenvolvedores veem Scala como uma linguagem que os ajudará a passar da programação orientada a objetos para a programação funcional. O uso do Scala pode tornar mais fácil para eles a transição para um estilo de programação totalmente funcional no futuro.
▍Python
O estilo de programação funcional é encorajado em Python. Isso pode ser entendido se levarmos em conta o fato de que cada função, por padrão, tem pelo menos um parâmetro -
self
. Em muitos aspectos, isso segue o espírito do " Zen Python ": "Explícito é melhor do que implícito."
▍Clojure
O Clojure, segundo o criador da linguagem, é cerca de 80% funcional. Todos os valores são imutáveis por padrão. Mas isso é exatamente o que é necessário para escrever código funcional. No entanto, você pode contornar isso usando contêineres mutáveis, nos quais os valores imutáveis são colocados. E se você extrair o valor do contêiner, ele se tornará imutável novamente.
▍Haskell
É uma das poucas linguagens totalmente funcionais e com tipagem estática. Embora usá-lo no processo de desenvolvimento possa parecer que leva muito tempo para implementar mecanismos funcionais, esse esforço será recompensado muitas vezes durante a depuração de código. Este idioma não é tão fácil de aprender quanto os outros, mas aprendê-lo é definitivamente um investimento que vale a pena.
Resultado
Deve-se notar que agora ainda é o início da era do big data. O big data está chegando, e não sozinho, mas com um amigo - com programação funcional.
A programação funcional, quando comparada à programação orientada a objetos, ainda é um fenômeno de nicho. No entanto, se considerarmos a integração dos princípios do FP em Python e outras linguagens como um fenômeno significativo, podemos concluir que a programação funcional está ganhando popularidade.
E isso faz sentido, uma vez que a programação funcional mostra-se bem no trabalho com bancos de dados, em programação paralela, no campo do aprendizado de máquina. E na última década, tudo isso tem aumentado.
Embora o código orientado a objetos tenha incontáveis benefícios, você não deve desconsiderar os benefícios do código funcional. Se um programador aprende alguns dos princípios básicos do PF, então isso, na maioria dos casos, pode ser suficiente para melhorar seu nível profissional. Esse conhecimento também o ajudará a se preparar para um “futuro funcional”.
Como você se sente em relação à programação funcional?
