Linguagens de programação funcionais: pra que preciso? (para salvar o planeta!)

Olá,

faz algum tempo que não escrevo pois ando meio sem tempo (isso existe?) devido ao meu novo emprego, mas estava dando uma estudada em um assunto de minha preferência e resolvi arrumar um tempo para compartilhar com vocês.

Essa semana alguém no meu trabalho mencionou a linguagem de programação Scala. Como não resisto a dar uma olhada em uma nova linguagem de programação cada vez que aparece uma, dei uma rápida olhada na net sobre o assunto. Confesso que não fiquei muito surpreso ao descobrir que Scala é uma linguagem multi-paradigma (orientada a objetos, funcional, imperativa?).

Sendo assim, no momento em que pus meus olhos sobre alguns exemplos de código Scala me veio à cabeça uma lembrança: F#. A similaridade entre as duas linguagens reside no fato de ambas serem linguagens funcionais. Entretanto, apesar de semelhantes, cada uma possui uma abordagem diferente. Enquanto Scala procura integrar o paradigma funcional com o paradigma OO, F# tende a ser mais puramente funcional. Scala vai muito bem com Java, apesar de ter uma versão dot.net, enquanto F# se integra muito bem à plataforma da Microsoft (já que esse era o objetivo). Sendo assim F# se torna forte candidata quando o objetivo for a criação de aplicações desktop (Windows Forms). Por outro lado Scala é sem dúvida a opção para os desenvolvedores Java, já que a primeira pode utilizar bibliotecas desenvolvidas pela segunda e vice-versa.

Seja lá qual for a sua preferência ou necessidade, F# e Scala me parecem as opções mais promissoras no que diz respeito à linguagens funcionais. Apesar de existirem diversas linguagens funcionais disponíveis atualmente (Erlang, Haskell, etc.), na minha opinião, para que uma linguagem de programação se torne comercialmente e amplamente utilizada durante um longo período de tempo, é necessário mais que fãs e uma comunidade apaixonada dando apoio. É preciso suporte e investimento corporativo (sim estou falando de dinheiro), ou seja, é necessário que alguém banque a idéia. É claro que outros requisitos são necessários, mas levando-se em conta a similaridade entre as diversas linguagens de programação, acho que o que definiu o sucesso de umas e o fim (comercial) de outras até hoje foi a presença (ou ausência) de suporte comercial.

Dito isso, alguém deve estar se perguntando… tudo bem, entendi, Scala e F# são (em tese) as melhores opções comerciais de linguagens multi-paradigma-funcionais, mas e daí? Pra que eu (desenvolvedor/empresário/curioso/qualquer um) preciso de uma linguagem assim?

Bem, nesse momento eu gostaria de fazer uma pausa e aproveitar a sensação de dizer: “Eu não te disse?” ou “Eu já sabia!”… Pronto… posso continuar.

Um assunto que venho disseminando entre colegas, e que foi alvo de um artigo meu (ainda não publicado que eu saiba, né Professor?) e que pretendo abordar em breve aqui no blog é o que eu chamo de “crise do paradigma sequencial na era do multi-processamento” (acabei de batizar). Mas o que vem a ser isso?

Bem, até bem pouco tempo processadores de múltiplos núcleos não eram uma realidade. Os programas escritos aumentavam de desempenho a medida em que os processadores ganhavam mais poder de processamento. Não era necessário alterar uma linha de código para obter mais desempenho. Entretanto por motivos físicos, comerciais e outros que nem imagino, não é mais viável o aumento de velocidade dos processadores na mesma escala em que isso vinha acontecendo. A solução encontrada pela indústria de hardware para fornecer mais capacidade computacional foi o desenvolvimento de processadores com múltiplos núcleos, os famosos dual-core, quad-core e há previsões para processadores de 80 núcleos e, bem mais que isso, em um futuro bem próximo.

Mas e daí? O que isso tem a ver com meus programas? Bem imagine que as instruções de seu programa são matéria prima de uma linha de produção. Agora imagine que na época dos processadores de núcleo único, bastava aumentar a velocidade da linha de produção para aumentar a velocidade do programa em execução, quer dizer, do processo. A questão é que seus funcionários por mais bem treinados que sejam possuem um limite de produtividade.

O que fazer então? Que tal montar uma linha de produção em paralelo? Dessa forma eu posso duplicar a minha produção, correto? E se eu colocar quatro linhas de produção em paralelo (processadores quad-core) eu irei quadruplicar a minha produção (a velocidade dos meus programas), correto? Errado.

O problema é que nem todas as tarefas de um processo ou programa podem ser paralelizadas. Em um artigo futuro eu pretendo entrar em detalhes com relação a esse assunto, mas por hora o importante é saber que nossos programas desenvolvidos em linguagens de programação tradicionais (c, java, etc.) não possuem (na maioria dos casos) um ganho de desempenho sensível quando executados por processadores de múltiplos núcleos.

É claro que podemos utilizar essas linguagens para modificar ou criar programas que utilizem threads, permitindo dessa forma a execução de instruções em paralelo. O problema é que fazendo isso nós acabamos por compartilhar nossas estruturas de dados (classes, variáveis, etc.) entre threads concorrentes o que pode acarretar problemas.

É claro, mais uma vez, que podemos utilizar técnicas de programação concorrente, como locks, semáforos, etc, mais que inegavelmente são mais complexas, além de serem um convite a uma série de problemas inerentes ao uso dessas técnicas.

Que tal então se utilizássemos uma linguagem de programação que fosse nascida para a concorrência e o paralelismo? É aí que se encaixam as linguagens funcionais e aonde reside o objetivo desse post. Não que elas tenham sido criadas com esse objetivo, mas devido a sua natureza, aonde funções são entidades de primeira ordem (funções recebem funções como parâmetros e retornam funções como resultado), os problemas com concorrência praticamente não existem.

Linguagens puramente funcionais como Haskell e Erlang obtém melhores resultados quando utilizadas para solucionar problemas de concorrência já que F# e Scala estão presas a arquitetura estrutural das suas respectivas máquinas virtuais. Entretanto por permitirem uma fácil integração com bibliotecas e código OO tradicional, me parece que essas linguagens podem vir a ser amplamente utilizadas, quando performance, paralelismo e concorrência forem questões vitais do programa a ser desenvolvido.

A conclusão que gostaria que os leitores desse post chegassem é a de que nossos programas sequenciais estão desperdiçando poder computacional e consequentemente dinheiro. Se imaginarmos que cada computador fabricado possui um custo ambiental atrelado a si, podemos dizer que nossos programas sequenciais contribuem para a degradação do meio ambiente. Para quem acha que estou viajando, vou me utilizar de analogia. Um computador multi-core executando um programa sequencial é o mesmo que um carro transportando somente uma pessoa, ou seja, um desperdício. Enquanto que para uma pessoa comum as duas coisas podem não parecer tão graves, para empresas e governos os dois assuntos são  (ou ao menos deveriam ser) tratados com preocupação. Mesmo que seja simplesmente para economizar dinheiro (no caso dos governos, o nosso).

Termino fazendo um convite à comunidade de desenvolvedores que comecem a estudar esse tema já que as linguagens de programação funcionais podem ajudar a salvar o planeta!

Abraço e até a próxima!

One thought on “Linguagens de programação funcionais: pra que preciso? (para salvar o planeta!)

Leave a comment