Skip to content

Instantly share code, notes, and snippets.

@edudobay
Last active August 29, 2015 14:07
Show Gist options
  • Save edudobay/429f8e3b701fee389b6f to your computer and use it in GitHub Desktop.
Save edudobay/429f8e3b701fee389b6f to your computer and use it in GitHub Desktop.
linguagem funcional

linguagem funcional

qual a definição de fatorial? um matemático poderia me responder algo assim:

fatorial(1) = 1
fatorial(n :: n Inteiro, n > 1) = n * fatorial(n-1)

como eu represento isso numa linguagem de programação? se você está acostumado com linguagens imperativas, poderia escrever um programa desse tipo:

fatorial(n):
   var resultado = 1
   for i = 1 → n
      resultado ← resultado * i
   return resultado

no entanto, numa linguagem funcional, a resposta do matemático já é uma resposta! por exemplo, em Haskell, eu realmente escreveria dessa forma:

fatorial :: Integer -> Integer
fatorial 1 = 1
fatorial n = n * (fatorial (n - 1))

a ideia é que uma operação seja vista como um encadeamento de pequenas operações que podem ser vistas como aplicações de "regras" — em oposição a operações algorítmicas que são vistas como sequências de passos.

um dos grandes lances de usar programação funcional é que uma função SEMPRE devolva o mesmo resultado dadas as mesmas entradas, e que a função não tenha ~efeitos colaterais~. então ela não pode mexer em variáveis externas, nem com qualquer coisa que tenha um ~estado~.

essa função aqui embaixo tem efeitos colaterais, por exemplo. isso não é permitido numa linguagem puramente funcional.

(em algum lugar...)
massaSolarKg = 1.98892e+30

(mais adiante...)
fatorial(n):
   var resultado = 1
   for i = 1 → n
      resultado ← resultado * i
      massaSolarKg ← massaSolarKg * i
   return resultado

(cuidado! talvez algum buraco negro surja ao executar esta linha...)
print fatorial(100)

um problema frutífero

suponha que eu tenha um array de frutas e outro array com o mesmo tamanho dizendo a quantidade de cada fruta que tem na minha fruteira:

frutas = ["banana", "laranja", "limão", "pêssego", "abacate"]
estoque = [3, 7, 11, 5, 18]

agora quero saber quais frutas estão em excesso. numa linguagem imperativa eu posso fazer algo com a seguinte lógica:

for i = 1 → num(frutas)
   if estoque[i] > 10
      print "Tem " + frutas[i] + " pra caramba!"

ou seja, eu escrevi pro computador um algoritmo passo a passo do que ele deve fazer. uma sequência de passos que ele deve executar.

agora vamos traduzir isso para uma pseudo-linguagem funcional. para facilitar o entendimento inicial, vou decompor em etapas. apesar de haver uma sequência, não é uma sequência de passos! é apenas uma sequência de definições que se encadeiam. as linhas com >>> indicam o resultado de cada etapa.

frutas = ["banana", "laranja", "limão", "pêssego", "abacate"]
estoque = [3, 7, 11, 5, 18]

mensagem_fruta(nomeFruta, estoqueFruta) :=
  { "Tem " + nomeFruta + " pra caramba!" } se estoqueFruta > 10
  { nulo } caso contrário

mensagens = [mensagem_fruta(frutas[i], estoque[i]) | i = 1 → num(frutas)]
>>> [nulo,
     nulo,
     "Tem limão pra caramba!",
     nulo,
     "Tem abacate pra caramba!"]

mensagens_para_imprimir = filtraNaoNulo(mensagens)
>>> ["Tem limão pra caramba!",
     "Tem abacate pra caramba!"]

mensagem_para_imprimir = junta("\n", mensagens_para_imprimir)
>>> "Tem limão pra caramba!\nTem abacate pra caramba!"

dá pra eu resumir tudo isso em um passo só:

frutas = ["banana", "laranja", "limão", "pêssego", "abacate"]
estoque = [3, 7, 11, 5, 18]

mensagem_para_imprimir = junta("\n", filtraNaoNulo([
      { "Tem " + frutas[i] + " pra caramba!" } se estoque[i] > 10
      { nulo } caso contrário
   | i = 1 → num(frutas)]))

que é toda a ideia da programação funcional: essa operação que eu fiz se resume a um encadeamento de funções.

nesse exemplo a versão funcional acaba ficando mais longa — a ideia era pegar um exemplo simples qualquer e traduzir as ideias para o pensamento funcional. mas há de fato muitos casos em que o estilo de programação mais funcional acaba de fato compactando o código, ou no mínimo deixando-o mais organizado e legível.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment