Da orientação a objetos ao paradigma funcional

Augusto Mesquita
LazyDev
Published in
5 min readOct 13, 2019

Com o destaque que o javascript ganhou nos últimos anos, muitas pessoas passaram a vê-lo como uma possibilidade real de uso até mesmo para aplicações mais complexas, principalmente porque a linguagem pode ser usada tanto no front-end quanto no back-end. Isso é uma coisa muito poderosa, especialmente para aqueles projetos de “equipe de desenvolvedores de uma pessoa”.

Por essas razões e mais algumas outras, várias pessoas do paradigma POO (programação orientada a objetos) começaram a migrar para esta nova forma de desenvolvimento e muitos caíram na armadilha de continuar a pensar de forma orientada a objetos em um mundo onde não serve mais.

Um desenvolvedor que é totalmente adepto de OOP, ao analisar um problema, irá naturalmente começar a rabiscar uma possível solução pensando em entidades, atributos e relacionamentos. E não é assim que a programação funcional funciona.

Uma breve introdução ao paradigma funcional

Em programação funcional, como o próprio nome diz, iremos utilizar funções para representar nossas aplicações. Isso significa que podemos pensar na programação funcional como um fluxo, o qual é formado somente por inputs e outputs.

Um exemplo muito simples de código no estilo não funcional (imperativo) vs funcional:

// Non-functional (imperative)
var name = "Augusto";
var greeting = "Olá, meu nome é ";
console.log(greeting + name);
// Funcional
function greet(name) {
return "Olá, meu nome é " + name;
}
greet("Augusto");

Até agora tudo bem. No entanto, as coisas começam a ficar um pouco confusas para os aventureiros de primeira viagem quando falamos sobre alguns conceitos que ajudam a programação funcional a funcionar de forma mais coesa, como:

  • Pure functions;
  • High-order functions;
  • Imutabilidade.

Funções puras para prevenir side effects

Ao lidar com a programação funcional, é uma boa prática sempre usar funções puras para evitar efeitos colaterais. Chamamos a função pura de uma função capaz de gerar uma saída válida apenas pelo processamento das entradas.

Funções não puras geralmente têm efeitos colaterais, pois usam mais do que apenas as entradas para criar uma saída, ou seja, o fato de usar coisas fora do escopo da função gera um efeito colateral. Exemplo de funções puras vs função não pura:

// ========= Not pure =========
var name;
function hiNotPure() {
return "Olá, meu nome é " + name;
}
// ========= Pure =========
function hiPure(nome) {
return "Olá, meu nome é " + nome;
}

Um dos segredos para dominar a programação funcional é pensar nas coisas da forma mais pura possível. Observe que no exemplo acima, a função hiNotPure usa a variável de nome que foi declarada fora de seu escopo.

Isso impede que a função seja autossuficiente, necessitando de elementos externos para processar as entradas e criar uma saída válida, o que pode causar problemas.

Manter uma função pura nos deixa mais confiantes sobre o que esperar de seu retorno e fornece um maior nível de garantia de que nenhuma mudança de estado que possa afetar futuras chamadas para essa função ocorra.

Um dos segredos para dominar a programação funcional é pensar nas coisas da forma mais pura possível.

High-order functions

Este é um tipo de função muito comum na programação funcional. Ele basicamente tem outra função em troca, o que não tira a função pura característica de tais funções.

Usando este tipo de função é possível sair de várias situações que seriam resolvidas de forma diferente usando o pensamento de outros paradigmas e que provavelmente tornariam as funções em funções não puras. Por isso, high-order functions acabam tendo grande importância no paradigma funcional.

Com esse tipo de função, é possível construir camadas de funções dentro de funções. Exemplo de uma high-order function:

function adjectiveCreator(adjective){
return function(element) {
return adjective + " " + element + "!";
};
}
var adjectiveWithGreat = adjectiveCreator("Great");
adjectiveWithGreat("article");
// Result: "Great article!"

Tip: Alguns exemplos de high-order function que o javascript nos oferece forma bult-in são: map, filter e reducer. A iteração de elementos usando o tradicional “for” provavelmente transformará uma função em uma função não pura ou quebrará a próxima regra de imutabilidade que será explicada abaixo.

Imutabilidade

Na programação funcional, devemos evitar a mudança de elementos. Isso significa que se quisermos modificar o conteúdo de um elemento, devemos criar um novo elemento com essa mudança. O exemplo a seguir mostra uma situação de mutabilidade e imutabilidade.

// =========  Mutability =========
var personAges = [10, 23, 31];
personAges[2] = 33;
personAges;
console.log(personAges);
// Result -> [10, 23, 33]
// ========= Immutability =========
var personAges= [10, 23, 31];
var newPersonAges = personAges.map(personAge => personAge == 31 ? 33 : personAge);
console.log(newPersonAges);
// Result -> [10, 23, 33]

A imutabilidade é importante, pois garante que o controle sobre o estado do elemento seja mantido. Isso nos permite confiar nos dados, pois eles não sofrerão alterações inesperadas ao longo do tempo. Controlar os dados de forma imutável pode custar uma boa quantidade de recursos se um bom controle dos dados não for feito.

Existem várias bibliotecas para javascript que foram criadas exclusivamente para usar closures da maneira mais eficiente possível, mantendo os dados imutáveis, como Mori e Immutable.js.

Mas qual é o melhor paradigma? Orientado a objetos ou funcional?

Não há resposta genérica pra isto. Dpenderá da necessidade, do contexto e de outros fatores.

Por exemplo, um projeto de livraria onde você tem livros e pessoas, tais elementos são facilmente representados no mundo orientado a objetos, pois são fáceis de imaginar.

No entanto, existem situações em que a ideia de entidades não faz sentido, e o desenvolvedor frequentemente se esforça para criar nomes colaborativos para objetos que funcionam quase exclusivamente como DTO (Data Transfer Object), criando apenas um grande CRUD para tudo na aplicação… Nestes casos, o paradigma funcional cairia muito bem.

Espero que esta informação tenha sido útil para quem está entrando ou pretende entrar no mundo da programação funcional.

Vejo você em breve!

--

--

Augusto Mesquita
LazyDev
Writer for

Um simples amante da programação e fã de Game of Thrones! Instagram:@augustomesquitasrs