Pressione enter para ver os resultados ou esc para cancelar.

Programação Funcional em JavaScript usando Ramda

Programação funcional é um tema que vem ganhando tração no mundo do JavaScript, principalmente por algumas características da linguagem que permitem que muita coisa seja feita nesse estilo e pelas vantagens que esse paradigma traz pro desenvolvimento web. Entretanto o JavaScript não é uma linguagem funcional e possui diversas limitações e para superá-las é necessário o uso de bibliotecas.

Lodash e Underscore trouxeram para o JavaScript uma maneira mais declarativa de transformar dados e compor novas funções. Uma das principais inovações dessas bibliotecas foi o uso de chains para transformar dados. Ainda assim, esse estilo de escrita difere bastante da forma usada por linguagens funcionais e é isso que o Ramda tenta resolver.

Através do Ramda é possível escrever um sequência de funções nessa forma:

É possível perceber que o dado não é referenciado na declaração da função, não há nenhuma variável que referencia o dado e isso permite que o desenvolvedor abstraia um pouco a execução da função e foque mais na composição das funções que vão gerar o resultado esperado.

Uma coisa interessante é que o Lodash permite esse tipo de escrita, só que é necessário fazer dois ajustes: fazer o curry da função e trocar a ordem dos parâmetros, assim o dado vai ser passado por último: E.g: map(array, fn) vira map(fn, array).

Dessa forma todas as funções desse pipe vão receber um array no último parâmetro, e enquanto elas não tiverem todos seus parâmetros preenchidos, elas vão retornar outra função, fazendo com que esse pipe execute de forma lazy, só executando quando receber o dado passado no último parâmetro. Essa é a principal diferença entre Ramda e Lodash/Underscore, todas as funções têm curry e o dado é passado no último parâmetro.

Para entender mais sobre currying leia o artigo Programação Funcional Parte 2.

Até agora não foram mostradas muitas vantagens em relação ao Lodash além do jeito de escrever, que é algo bastante subjetivo. Mas existe algo que o Ramda permite fazer mais facilmente que é a inclusão de funções customizadas. Para fazer isso no Lodash seria necessário incluir essa função utilizando o _.mixin().

Enquanto que com Ramda basta escrever uma função normal em JS.

Imutabilidade

As funções da biblioteca não modificam os dados recebidos nos parâmetros. Isso é importante pois imutabilidade é um dos princípios da programação funcional e garante maior segurança.

Para entender mais sobre imutabilidade leia o artigo Programação Funcional Parte 1.

Composabilidade

Composição de funções é uma das coisas mais importantes ao se trabalhar com programação funcional. Composição pode ser definida como:

Onde f e g são funções e x é o valor que vai ser passado para essas funções.

O Ramda oferece uma implementação mais robusta da função compose(), podendo receber inúmeras funções de aridade um e retornando uma função que recebe uma estrutura de dados. Assim que o dado for passado a sequência de funções vão ser executadas da direita para a esquerda.

Os exemplos anteriores usavam uma função chamada pipe() que tem um comportamento parecido com o do compose() mas que executa da esquerda da direita sendo assim mais fácil de ler.

Lens

Lens é um objeto que possui um getter e um setter para uma subestrutura na qual a lens foi “focada”. Ela recebe duas funções: uma função que age como getter e outra como setter, e retorna um objeto do “tipo” Lens. É possível entender lens como uma lente que foca em uma parte do dado.

A função prop recebe o nome de uma propriedade e um objeto e retorna o valor de uma propriedade naquele objeto; é o nosso getter.

Já a função assoc() recebe o nome de uma propriedade, um valor e um objeto e retorna um novo objeto com a propriedade tendo um novo valor; é o nosso setter.

Junto com o lens, o Ramda traz algumas funções que recebem o lens como parâmetro, elas são view(), set() e over().

View() permite tu ver aonde a lens (lente) está focando

Set() serve para mudar o valor de uma propriedade

Over() vai mudar o valor da propriedade passando ela por dentro de uma função

Caso de Uso de Lens

Imagine que queremos filtrar posts de um usuário pelo número de likes. Usando somente composição não teríamos como fazer essa filtragem, pois a função filter() vai retornar um array e não todo o objeto que estamos trabalhando.

Com lens isso é possível

Lens também podem ser compostas, mas a ordem da composição é inversa, vai da esquerda pra direita

Conclusão

Espero que esse artigo tenha aumentado a curiosidade de vocês sobre programação funcional e como é possível começar a usar um pouco dela no mundo JavaScript através de bibliotecas como o Ramda ou outras que seguem a mesma linha como o Lodash/fp e o Sanctuary.

Deixe nos comentários suas dúvidas ou críticas e até a próxima.


***
📣
Estamos contratando pessoas que desenvolvam software!
Mais informações sobre a vaga.
***