Codemountain, Paulo Suzart's Blog

5 coisas para tornar o seu cérebro funcional

leave a comment »

Desde janeiro de 2009, no meu primeiro post sobre Scala, venho na verdade falando de um paradigma desafortunadamente não ensinado na maioria das universidades brasileiras: Programação Funcional. Se alguém tem/teve aulas de programação funcional na universidade por favor deixe o nome da instituição nos comments.

O que percebi nestes dois anos de posts sobre programação funcional e duas (Scala e Clojure) das linguages que suportam este paradigma, é que muitos leitores sentem uma dificuldade em se livrar das suas raizes imperativas, e a syntax destas linguagems acabam ficando até como uma dificuldade em segundo plano.

Por isso resolvi escrever este post compacto que serve mais como direcionamento para tornar o seu cérebro funcional. Aqui vão 5 coisas que vão ajudar o programador a atingir seu momento de iluminação funcional:

1. Lambda Calculus

Estude essa coisa. Lambda Calculos, em muito alto nível, é a raiz da programação funcional. Neste cálculo, tudo é uma função, inclusive os números naturais, as operações algébricas, etc. Este sistema formal, possui uma série de colorários e propriedades que vão embasar as linguagens de programação funcional. E não, eu não sou especialista em Lambda Calculus e estou longe de ter fôlego intelectual pra isso. Mas ver a introdução é um bom começo pra se sentir confortável.

2. Diga ‘o quê’, não ‘como’

Isto está bastante ligado a funções de alto nível (High-order functions). São aquelas funções que recebem funções como argumento e até mesmo retornam alguma função. Fortes exemplos de funções de alto nível são funções de mapeamento em listas. Ou seja, você tira da sua responsabilidade a iteração de uma sequencia e informa para a função de mapeamento, qual função você quer aplicar nos elementos da sequencia. Exemplo:

(def numbers (range 5))
(map #(* % %) numbers);; obtem o quadrado de cada ítem da lista de 0 a 4.

Aqui podemos ver a funções de alto nível map em ação, esta é provavelmente a função mais utilizada e mais exemplificada na internet. Mas é realmente prática e fácil de entender a coisa. Simplesmente pedimos que seja aplicada a função anônima que multiplica cada ítem por ele mesmo. Esta: #(* % %). Não vemos um for, iterações ou coisas do gênero.

3. Entenda funções parcialmente aplicadas

Elas são úteis. Você pode computar somente entradas pra uma função, mas ao invés de aguarda que você obtenha todas as entradas para ela, você pode começar a aplicar (invocá-la) com os parâmetros que você possue em mãos e passá-la a diante. Veja um exemplo: Usando o mesmo numbers acima, vamos computar a multipliação de cada ítem de 0 a 4 por algum número que ainda não conhecemos.

(def partials (map #(partial * %) numbers)))
(map #(% 2) partials);; = (0 2 4 6 8 )

partial também é uma função que recebe uma função (a função de multiplicação *) e um parâmetro para ser aplicado a esta função, no caso cada ítem da sequencia. partials é a minha lista de funções parcialmente aplicadas. Algo como: ((* 0 ?) (* 1 ?) (* 2 ?) (* 3 ?) (* 4 ?)). Wow! Interessante. A segunda funão no código acima aplica a função gerada na lista de partials ao 2. 2 é o número que gostariamos de multiplicar cada elemento de 0 a 4 inicialmente, lembra? Acredite, isso é útil demais e existem muitos frameworks usando fortemente funções parcialmente aplicadas.

4. Imutabilidade é natural

Este é o tópico que talvez tenha gerado o maior hype nesta história de programação funcional. O resultado foi um monte de final nas variáveis em java, na esperança de isso ser suficiente para programar funcional ou garantir alguma imutabilidade. Na verdade de nada adianta colocar final na variável da classe, digamos, Pessoa e todos os seus atributos não serem final. E aí vem: Mas clonar a cada set vai custar memória? Vai. Clojure resolve essa questões com estruturas de dados persistêntes. Aqui você encontra uma boa explicação sobre estas estruturas. Vamos a um exemplo: Pegue a lista numbers e faça um prepend do valor 5 nesta lista:

(cons 5 numbers);; o REPL mostrará (5 0 1 2 3 4)
numbers;; e o REPL mostrará novamente (0 1 2 3 4)

Isso deixa claro como numbers não vai mudar. A menos que você use algum artifício da sua linguagem (clojure: atoms, refs, vars, agents e pods brevemente) para acesso aos valores de uma identidade ao longo do tempo. Ainda assim, o que vai mudar é o para onde no tempo a sua identidade aponta, mas os valores nunca irão mudar. Assim como seu passado não mudará. Profundo. Mas não fica proibido o uso de alguma variável completamente mutável.

5. Recursividade não deve ser estranho

Funções recursivas por incrível que parece ainda causam confusão na cabeça da grandíssima maioria dos programadores. Este post de Michael Kohl (@citizen428) fala especificamente de Y Combinator que é implementado com um conjunto de funções recursivas, lambdas e high-order functions ao mesmo tempo. Entender este post é obrigatório se você quer seu cérebro afiado.

Além disso…

Na verdade existem conceitos mais profundos no universo funcional. Coisas que sinceramente são capazes de torcer o cérebro de qualquer um. Existem também outras linguagens que não estas que mais estudo como Erlang, Haskell (talvez a mais impressionante em termos conceituais e expressividade funcional), Scheme, Lisp, Racket (sensacional), e outras.

Programação funcional não é sobre moda, ou sobre “passar um método como argumento”, ou “sobre escrever um programa inteiro em uma linha só”. FP (Functional Programming) é sobre elaborar soluções focadas no problema, e de forma elegante e muito concisa. Ainda que não use no seu dia-a-dia, é de grande utilidade para suas próximas construções mesmo numa linguagem imperativa.🙂

É isso e não esqueça de me seguir no twitter: @paulosuzart.

Ah, este post deveria ter 10 itens. Estou buscando os demais itens no exterior. Espero conseguí-los. Este post teve apoio de @jneira.

Written by paulosuzart

janeiro 1, 2011 às 3:58 pm

Publicado em clojure

Tagged with ,

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: