Conceitos Essenciais em Programação Funcional com JavaScript

Mar 12 2023
A programação funcional é um paradigma que ganhou popularidade nos últimos anos devido à sua capacidade de escrever códigos mais modulares, reutilizáveis ​​e de fácil manutenção. JavaScript, sendo uma linguagem de programação versátil, também é adequada para programação funcional.
Conceitos de programação funcional em JavaScript

A programação funcional é um paradigma que ganhou popularidade nos últimos anos devido à sua capacidade de escrever códigos mais modulares, reutilizáveis ​​e de fácil manutenção. JavaScript, sendo uma linguagem de programação versátil, também é adequada para programação funcional. Neste artigo, exploraremos conceitos essenciais em programação funcional com JavaScript e como eles podem ajudá-lo a escrever um código melhor:

  1. Funciona como cidadão de primeira classe
  2. Funções de ordem superior
  3. Funções puras
  4. Imutabilidade
  5. Recursão

Na programação funcional, as funções são tratadas como cidadãos de primeira classe, o que significa que podem ser atribuídas a variáveis, passadas como argumentos para outras funções e retornadas como valores. Este conceito é crucial na programação funcional, pois nos permite escrever um código mais modular e reutilizável.

Aqui estão alguns exemplos de como as funções são tratadas como cidadãos de primeira classe em JavaScript:

  1. Atribuindo funções a variáveis:

const add = function(x, y) {
  return x + y;
}

2. Passando Funções como Argumentos:

As funções também podem ser passadas como argumentos para outras funções. Isso permite uma abordagem mais modular da programação, pois nos permite reutilizar a mesma função com entradas e saídas diferentes. Por exemplo:

function greet(name, callback) {
  const message = "Hello, " + name + "!";
  callback(message);
}

function logMessage(message) {
  console.log(message);
}

greet("Sumit", logMessage); // Logs "Hello, Sumit!"

3. Retornando funções como valores:

As funções também podem ser retornadas como valores de outras funções. Isso permite técnicas mais avançadas, como fechamentos e currying. Por exemplo:

function add(x) {
  return function(y) {
    return x + y;
  };
}

const addFive = add(5);
console.log(addFive(3)); // Logs 8

✓ Funções de ordem superior

Funções de ordem superior são funções que recebem outras funções como argumentos ou funções de retorno como valores. Eles nos permitem escrever um código mais abstrato e de uso geral que pode ser aplicado a diferentes casos de uso. Algumas funções comuns de ordem superior em JavaScript são map(), filter() e reduce().

Aqui estão alguns exemplos de funções de ordem superior em JavaScript:

  1. Array.prototype.map():

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function(num) {
  return num * 2;
});
console.log(doubled); // Logs [2, 4, 6, 8]

2. Array.prototype.filter():

O filter()método é outra função de ordem superior que usa uma função de retorno de chamada como argumento e retorna uma nova matriz com apenas os elementos que passam no teste especificado no retorno de chamada. Por exemplo:

const numbers = [1, 2, 3, 4];
const even = numbers.filter(function(num) {
  return num % 2 === 0;
});
console.log(even); // Logs [2, 4]

3. Function.prototype.bind():

O bind()método é uma função de ordem superior que retorna uma nova função com um thisvalor específico e argumentos iniciais. Geralmente é usado para criar uma nova função com um contexto específico ou para criar uma função parcialmente aplicada. Por exemplo:

const person = {
  firstName: "Sumit",
  lastName: "Saha",
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

const logName = function(greeting) {
  console.log(greeting + " " + this.fullName());
};

const boundLogName = logName.bind(person, "Hello");
boundLogName(); // Logs "Hello Sumit Saha"

Estes são apenas alguns exemplos das muitas funções de ordem superior disponíveis em JavaScript. Ao usar funções de ordem superior, você pode escrever um código mais genérico e reutilizável que pode ser aplicado a diferentes casos de uso.

✓ Funções Puras

Funções puras são funções que não possuem efeitos colaterais, ou seja, não modificam nenhum estado externo ou variáveis ​​fora de seu escopo. Eles sempre retornam a mesma saída para a mesma entrada, tornando-os determinísticos. As funções puras são essenciais na programação funcional, pois promovem a previsibilidade, testabilidade e manutenção do código.

Aqui estão alguns exemplos de funções puras em JavaScript:

  1. Função de adição:
  2. function add(a, b) {
      return a + b;
    }
    

function concatenateArrays(arr1, arr2) {
  return arr1.concat(arr2);
}

3. Função de formatação de data:

function formatDate(date) {
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  return `${year}-${month}-${day}`;
}

4. Função de capitalização de string:

function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

Em geral, funções puras são funções que não possuem nenhum efeito colateral e sempre retornam o mesmo resultado para a mesma entrada. Eles são previsíveis e fáceis de raciocinar, tornando-os ideais para escrever código reutilizável e sustentável.

✓ Imutabilidade

A imutabilidade é um conceito que envolve evitar a modificação de estruturas de dados ou variáveis ​​depois de criadas. Em vez de alterar um objeto ou array, criamos um novo com as alterações desejadas. Essa abordagem evita efeitos colaterais não intencionais e torna o código mais previsível e mais fácil de raciocinar.

Aqui estão alguns exemplos de imutabilidade em JavaScript:

  1. Usando o operador spread para criar um novo array ou objeto:
  2. const arr1 = [1, 2, 3];
    const arr2 = [...arr1, 4];
    // arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]
    
    const obj1 = { a: 1, b: 2 };
    const obj2 = { ...obj1, c: 3 };
    // obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }
    

const arr1 = [1, 2, 3];
const arr2 = arr1.concat(4);
// arr1 is still [1, 2, 3], arr2 is [1, 2, 3, 4]

3. Usando Object.assign()para criar um novo objeto:

const obj1 = { a: 1, b: 2 };
const obj2 = Object.assign({}, obj1, { c: 3 });
// obj1 is still { a: 1, b: 2 }, obj2 is { a: 1, b: 2, c: 3 }

4. Usando Object.freeze()para evitar a modificação de um objeto:

const obj1 = Object.freeze({ a: 1, b: 2 });
obj1.c = 3;
// obj1 is still { a: 1, b: 2 }, the assignment is ignored

Em geral, imutabilidade significa que os dados não são alterados diretamente, mas novas cópias são criadas quando as alterações são feitas. Isso pode ajudar a evitar efeitos colaterais indesejados e tornar o código mais previsível e fácil de manter.

✓ Recursão

A recursão é uma técnica em que uma função chama a si mesma para resolver um problema. É uma ferramenta poderosa na programação funcional, pois permite resolver problemas complexos decompondo-os em outros menores e mais simples. No entanto, a recursão pode ser complicada de usar, pois pode levar a erros de estouro de pilha e problemas de desempenho se não for usada corretamente.

Aqui estão alguns exemplos de recursão em JavaScript:

  1. Função fatorial:
  2. function factorial(n) {
      if (n === 0) {
        return 1;
      } else {
        return n * factorial(n - 1);
      }
    }
    
    factorial(5); // returns 120 (5! = 5 * 4 * 3 * 2 * 1)
    

function sum(arr) {
  if (arr.length === 0) {
    return 0;
  } else {
    return arr[0] + sum(arr.slice(1));
  }
}

sum([1, 2, 3, 4, 5]); // returns 15 (1 + 2 + 3 + 4 + 5)

3. Função de Fibonacci:

function fibonacci(n) {
  if (n === 0 || n === 1) {
    return n;
  } else {
    return fibonacci(n - 1) + fibonacci(n - 2);
  }
}

fibonacci(6); // returns 8 (0, 1, 1, 2, 3, 5, 8)

A recursão pode ser uma ferramenta poderosa na solução de problemas que envolvem padrões ou estruturas repetitivas. No entanto, também pode levar a problemas de desempenho e erros de estouro de pilha se não for implementado com cuidado. É importante entender o conceito de recursão e usá-lo criteriosamente em seu código.

Conclusão

Em conclusão, a programação funcional é um paradigma importante que pode ajudá-lo a escrever um código mais modular, reutilizável e sustentável. Compreendendo conceitos essenciais como funções como cidadãos de primeira classe, funções de ordem superior, funções puras, imutabilidade e recursão, você pode começar a escrever código mais funcional em JavaScript. A programação funcional não é a única maneira de escrever um bom código, mas é uma ferramenta poderosa que pode ajudá-lo a resolver problemas complexos e tornar seu código mais previsível e fácil de raciocinar.