A plataforma Java tem feito trabalhos importantes para auxiliar o desenvolvedor a suprir tais demandas. Neste artigo abordaremos as principais características da programação funcional, que se tornou uma possibilidade mais próxima do desenvolvedor Java após o lançamento do Java 8.
Veremos como escrever um código mais conciso, declarativo e estético utilizando as novidades desta versão com a introdução de Lambdas, Referências de Métodos e as novas classes da API de suporte à programação funcional.
Com estes novos recursos o desenvolvedor terá em suas mãos ferramentas eficientes para melhorar a qualidade do seu código e produzir aplicações com as características exigidas pelas demandas atuais.
Podemos pensar em um programa como uma estrutura sintática organizada de modo que, uma vez compilada e executada, gere um resultado semântico – neste caso, a execução de uma tarefa.
Desta forma, percebe-se que a escrita de um software tem muito em comum com a escrita textual: para ambos os casos existem muitas maneiras de estruturar e transmitir uma ideia, chegando ao mesmo resultado.
Sendo assim, como podemos identificar a melhor estrutura de escrita ou a melhor maneira de organizar um código? No campo da escrita textual, as recomendações estão sempre associadas a simplicidade, clareza e concisão, a fim de que o leitor consiga extrair o máximo de informação com o menor esforço de leitura.
Na escrita de software, estas recomendações se encaixam perfeitamente através de códigos simples, limpos e concisos para a facilitação da leitura e obtenção de melhor performance na execução.
Desta forma, a evolução das linguagens de programação revela um esforço determinante nesta busca pelo melhor modelo de escrita de código, sendo a Orientação a Objetos um marco importante no estilo de codificação de softwares em comparação com os anteriores, contribuindo para esses três pilares com o reaproveitamento de código, reutilização de abstrações, acoplamento de componentes, encapsulamento, polimorfismo, entre outros.
Até o Java 8 a programação funcional ainda era uma opção muito cara para o desenvolvimento em Java devido à natureza imperativa da linguagem que demandava muito esforço de estruturação, resultando muitas vezes em códigos menos legíveis.
Agora esta nova versão está adicionando recursos importantes para facilitar o desenvolvimento de novas ideias através da introdução das sintaxes para expressões Lambda e Referências de Métodos, além da adição de classes utilitárias à API.
Estas novidades flexibilizam a criação de códigos mais funcionais e oferecem ao desenvolvedor Java uma maneira diferente de expressar códigos com maior simplicidade e concisão, facilitando a sua manutenção e paralelização sem efeitos colaterais.
A programação funcional é um paradigma que visa estruturar a construção de softwares seguindo o modelo de funções matemáticas, objetivando a imutabilidade dos dados e o acoplamento de funções, que resultam em benefícios como consistência tanto do código quanto dos dados – veremos os porquês no decorrer do artigo.
Semelhante a uma função matemática, um código funcional tem a sua saída condicionada exclusivamente à sua entrada, de modo que uma entrada garanta sempre a mesma saída após a execução do mesmo método, eliminando os chamados side-effects, que são as mudanças de estado ocasionadas por outros fatores que não dependam dos parâmetros do método.
As bases da programação funcional são da década de 1930, a partir dos estudos do matemático norte-americano Alonzo Church na aplicação de modelos de funções matemáticas em computação, mais precisamente no Cálculo de Lambdas.
As primeiras aplicações práticas deste paradigma apareceram nas linguagens LISP (List Processing), quando elas começaram a ser influenciadas pelas ideias dos Cálculos de Lambda de Church.
Recentemente temos visto muitas linguagens que dão suporte à programação funcional emergindo e ganhando muitos desenvolvedores adeptos ao paradigma. Algumas delas rodando, inclusive, na JVM, como é o caso das linguagens Scala e Clojure.
A partir da versão 8 do Java, tanto a linguagem quanto a sua máquina virtual sofreram alterações consideráveis através de otimizações no núcleo da JVM e da modernização da linguagem com a introdução de Lambdas e melhorias na API com a adição de novas classes para não só permitir, como também facilitar e otimizar a programação funcional. Com isso o Java ganha ainda mais flexibilidade e força para se manter no topo como uma das linguagens mais utilizadas no mundo.
Neste artigo conheceremos estes novos aspectos do Java 8. Para isso, serão apresentados e demonstrados os principais conceitos da programação funcional, suas aplicações e implementações utilizando a nova sintaxe e API introduzidas na linguagem.
Mude o jeito de pensar
Para programar de forma funcional é preciso que o desenvolvedor mude a forma de pensar a construção dos seus algoritmos. Antes da versão 8, o modelo de programação na linguagem Java era imperativo; o que significa que para realizar uma iteração simples, por exemplo, o desenvolvedor tinha que se preocupar não somente com o que deveria ser feito com cada item da coleção iterada, mas também em como realizar a iteração e, em muitos casos, como filtrar os itens.
Este modelo facilitava, por natureza, erros como variáveis não inicializadas ou que mudam no decorrer da iteração, possibilitando que a mesma iteração tivesse resultados diferentes em função das mutações de variáveis de controle.
Além disso, esse modelo imperativo de programação dificulta a paralelização da tarefa efetivamente realizada dentro da iteração, visto que qualquer tentativa de paralelização pode envolver muitos controles de concorrência e de thread safety. Outra característica negativa do código imperativo é a sua legibilidade, já que a leitura do código envolve não somente decifrar a regra de negócio, mas também compreender as complexidades do controle de fluxo do algoritmo.
A programação funcional traz uma nova forma de pensar o fluxo do algoritmo ao introduzir o conceito de programação declarativa, cujos principais benefícios são a imutabilidade de variáveis, eliminação de side-effects – já que a garantia de que uma variável não vai mudar dentro de um fluxo assegura que não existirão efeitos colaterais no mesmo código quando paralelizado – e obtenção de códigos mais concisos.
Um código conciso significa um código ao mesmo tempo breve, significativo e claro, de fácil legibilidade. Com todos estes aspectos reunidos, o resultado será um código muito mais fácil de manter e menos susceptível a erros.
Como ser declarativo
Já que a palavra de ordem na programação
funcional é programar de forma decl ...