A tendência para usar linguagens de programação funcional tem vindo a crescer constantemente nos últimos anos. À medida que a procura de sistemas computacionais se torna maior e mais complexa a cada ano que passa, os dados aumentam exponencialmente e as empresas ultrapassam os limites do software.
Programdores e arquitetos precisam de apresentar novas alternativas e soluções para enfrentar esses novos desafios.
Lisboa vai ser palco de um dos mais entusiasmantes eventos de linguagem funcional a nível Mundial, o LX Scala & Reactive 2019, nos dias 4 e 5 de Julho.
Inscreva-se e faça parte deste grande evento. Para usufruir de um desconto de 75% utilize o código pplware_lxscala.
A redescoberta dos conceitos e linguagens de Programação Funcional, juntamente com a integração de idiomas funcionais em linguagens e estruturas já existentes e bem estabelecidas, tem permitido aos programadores lidar com algumas dessas procuras com mais confiança, eficiência e eficácia.
O conceito de Programação Funcional não é novo, de facto a teoria fundamental que o apoia – “The Lamda Calculus” desenvolvido por Alonzo Church data dos anos 30.
A primeira encarnação da linguagem Lisp vem do final da década 50. Já o influente trabalho na família de linguagens ML data do início dos anos 70. Até mesmo Haskell, a linguagem puramente funcional mais usada, está prestes a completar 30 anos.
Em Programação Funcional existem alguns conceitos básicos, tais como:
- Funções de primeira ordem (First class and high order functions)
- Suporte para a criação de funções puras (explícitas ou não) e estruturas de dados imutáveis
- Sistemas de tipos poderosos e expressivos com base matemática (para linguagens tipificadas estaticamente)
Funções de primeira ordem são sem dúvida a característica mais relevante que tornam a Programação funcional possível. As inúmeras maneiras pelas quais as funções podem ser compostas e transformadas, especialmente em linguagens tipificadas, tornam-nas ideais para expressar muitos algoritmos a nível muito alto de abstração, muitas vezes mais próximo da terminologia do domínio de desenvolvimento do que a linguagem de programação ou a máquina.
Comparando com um estilo de programação mais imperativo, os programas funcionais geralmente são escritos de forma mais declarativa – o “o quê” e não o “como” – preferindo declarações de dados, correspondência de padrões e composição de funções num conjunto de etapas consecutivas explícitas a serem executadas.
A programação funcional pode ser aplicada a várias linguagens de programação, não apenas aquelas consideradas “funcionais”. Por exemplo, Javascript permite funções de primeira ordem desde a sua concepção.
Java 8 e C ++ introduziram expressões de Lambda e muitas bibliotecas de inspiração funcional baseadas nelas. Scala combina os paradigmas funcionais e orientados a objetos numa linguagem coerente, que muitos programadores estão a usar para apresentarem padrões e conceitos avançados de Programação Funcional.
Até mesmo a linguagem SQL emprega funções puras para fazer projeções e agregações em contexto de álgebra relacional. O Microsoft Excel pode ser visto como a aplicação mais popular da Programação Reativa Funcional disponível.
A programação funcional está, portanto, presente em muitas das linguagens disponíveis e conhecidas atualmente.
Imutabilidade, concorrência e paralelismo
Sabe-se que a imutabilidade e a concorrência, são ambos pontos de venda comuns para a programação funcional. Por imutabilidade referimo-nos à programação sem mutação (mudança) de variáveis (portanto, nenhuma variável) . Sendo aquelas diretamente acedidas pelo programa ou estado interno de alguma estrutura ou objeto.
Isso combina perfeitamente com o uso de funções puras, dado que essas funções apenas copiam e modificam estruturas existentes, em vez de mutação no local. É, no entanto, necessário repensar a forma como as estruturas de dados comumente usadas são implementadas: listas, mapas, conjuntos, filas, etc. (Okasaki, 1999).
Como a mutação no local é permitida e cópias profundas da estrutura de dados são geralmente caras em termos de velocidade de memória e computação, a partilha de partes estruturais comuns é a chave para o desenvolvimento eficiente de estruturas de dados imutáveis.
Muitas das implementações de estrutura de dados imutáveis existentes são bastante diretas, como por exemplo, a lista de links únicos. No entanto, para estruturas de dados úteis em cenários mais flexíveis, foi necessário haver um afastamento das implementações comuns baseadas em array, criando estruturas baseadas em árvores como 2-3 Finger Trees (Hinze e Paterson 2006) ou Clojure’s Persistent Vectors.
Interfaces Reativas ao Utilizador
A aplicabilidade da programação funcional no desenvolvimento da interface do utilizador já é conhecida há algum tempo, mesmo que não se observe de forma explícita.
Um bom exemplo disso é o React Web Framework do Facebook, que já está em voga há algum tempo no universo em constante mudança das bibliotecas JavaScript. Em React, programador escreve funções “puras” que recebem como entrada o estado atual da aplicação – designado por modelo – e são responsáveis por retornar a nova renderização da interface do utilizador.
React é então responsável por calcular as diferenças entre a visualização anterior e a atual (geralmente na forma de HTML) e renderizar novamente no browser apenas o que foi alterado. Quando algum evento como a entrada do utilizador é processado pelo React, outra função pura, fornecida pelo programador, é responsável por retornar a nova aplicação resultante das possíveis alterações causadas pelo utilizador.
Isso irá refletir imediatamente as mudanças de exibição e assim por diante. A linguagem de programação Elm é uma implementação deste princípio apoiada por React, com a semântica da interface do utilizador reativa incorporada na própria linguagem (Czaplicki e Chong 2013).
Processamento de Dados
Os pipelines de processamento de dados são compostos por etapas discretas e independentes que manipulam e transformam elementos de dados, ao longo de um fluxo de operação geralmente sequencial. Seja em processamento em lote ou em cenários de streaming em tempo real, a programação funcional é adequada para descrever essas transformações como funções puras.
Estruturas de processamento de dados inspiradas funcionalmente são baseadas num conjunto comum e restrito de operações, e formas de compô-las dentro de pipelines. Mapear (transformar), filtrar ou agregar dados é a base para muitos dos algoritmos usados atualmente na análise e processamento de big data.
O framework Spark (Zaharia et al. 2010), disponível para muitos idiomas, é uma das ferramentas mais usadas para fazer análise de big data, sistemas de recomendação de código ou trabalhos de machine learning. Ele emprega combinadores funcionais e ideias conhecidos para fornecer aos programadores uma forma padrão de executar cálculos baseados em dados, seja numa única máquina de desenvolvimento local ou num cluster distribuído de máquinas de processamento de alta potência.
O alto nível de abstração fornecido pelo Spark, permitindo que o programador não se preocupe com a forma ou o local onde os dados são localizados ou processados, permite um desenvolvimento muito rápido e eficaz de pipelines de dados, fornecendo aos programadores mais tempo para se concentrarem em soluções específicas de domínio do que sobre os detalhes da computação distribuída na maior parte do tempo. Prevemos que o processamento de dados se torne como uma das principais áreas em que os conceitos de Programação Funcional são e serão aplicados no futuro próximo.
O poder da computação virtualmente infinita que as ofertas atuais na nuvem fornecem, juntamente com as enormes quantidades de dados que precisam ser consumidos e processados pelas empresas, fornecem as bases para a programação funcional crescer e ajudar os programadores nos seus projetos.
Tópicos Adicionais
Seria impossível cobrir todo e qualquer cenário em que a Programação Funcional possa ser aplicada ou relevante. No entanto, além daqueles já descritos, pode-se encontrar o uso pesado de FP, ou seja, a programação funcional tipada, em sistemas críticos (às vezes formalmente verificados), indústrias bancárias e FinTech e soluções de machine learning A/I.
Sistemas de tipos potentes levam a software mais correto com garantias muito robustas. Com sistemas de tipo suficientemente poderosos, pode-se até encontrar equivalência entre proposições lógicas e programas de computador, com a fantástica consequência de ter programas formalmente comprovados de graça (Wadler 2015).
Também é importante afirmar que, apesar da pesada base teórica da Programação Funcional, não é necessário nenhum doutoramento em álgebra abstrata para ser produtivo. Embora linguagens mais funcionais, como Haskell ou Scala, sejam mais adequadas para esse paradigma – Haskell não fornece nenhuma outra maneira – é possível aplicar conceitos e práticas de Programação Funcional em todos os lugares em que as funções podem ser armazenadas e passadas, pelo menos.
Em suma, os sistemas de tipos fornecem mais verificações ao nosso código, evitando muitos bugs comuns e a compilação de programas incorretos. A imutabilidade evita preocupações partilhadas de estado e concorrência. Quando isso não for possível, abstrações de nível superior sobre estado mutável e paralelismo, compostas usando funções puras, podem levar a um melhor modelo de programação concorrente e distribuída, comparando com código imperativo.
O sucesso da React e as técnicas de programação reativa funcional, em geral, provaram ser muito adequadas para o desenvolvimento da Interface do utilizador, ou seja, no contexto de aplicações Web e móveis.
Acreditamos que, com a crescente popularidade de técnicas e idiomas de programação funcional e a sua aplicação num amplo espectro de campos e cenários, programadores e arquitetos capazes e familiarizados com o FP podem-se posicionar melhor para enfrentar os desafios que o desenvolvimento de software futuro pode trazer.
Lisboa vai ser palco de um dos mais entusiasmantes eventos de linguagem funcional a nível Mundial, o LX Scala & Reactive 2019, nos dias 4 e 5 de Julho.
Inscreva-se e faça parte deste grande evento. Para usufruir de um desconto de 75% utilize o código pplware_lxscala.