Concrete Logo
Hamburger button

Currying vs Aplicação Parcial

  • Blog
  • 12 de Dezembro de 2018

Com a Programação Funcional de volta ao hype, os termos Currying e Aplicação Parcial (Partial Application) estão cada vez mais recorrentes nas conversas da comunidade. Porém, existem diversos conteúdos pela internet incorretos sobre o tema.

A missão deste artigo é de desmistificar a diferenças entre estes dois conceitos distintos da forma mais descomplicada possível.

Antes de começarmos

Apesar de os exemplos terem sidos escritos em JavaScript, os conceitos são agnósticos quanto à linguagem de programação. O que pode mudar é a forma em que outras linguagens permitem sua implementação.

Dito isso, vamos a algumas definições para melhor entendimento do texto:

Argumentos

São os valores fornecidos a uma função no momento de sua execução.

Parâmetros

Variáveis nomeadas dentro de uma função que recebem os valores fornecidos (argumentos). Ou seja, os parâmetros guardam/referenciam os argumentos passados na hora da execução da função.

Aridade

Aridade se refere ao número de argumentos que uma função aceita. Podendo assim, receber nenhum (nulária), um (unária), dois (binária) ou mais argumentos (poliádica). Existem também funções que aceitam um número variável de argumentos, chamadas de funções variádicas.

Aplicação

Processo de aplicar uma função a seus argumentos para produzir um valor em retorno.

Pense na palavra “aplicar” do mesmo modo que aplicamos uma função para cada valor de uma lista quando usamos um ‘map’. Por exemplo:

Agora sim estamos prontos para começar.

Currying

Vejamos primeiro a definição de Currying:

Em ciência da computação e na matemática, Currying é a técnica de quebrar uma função de aridade superior a 1 em uma cadeia de funções unárias.

Por exemplo, pensando em uma função que necessita de 3 parâmetros para realizar um cálculo, sua versão sem utilizar Currying seria:

Nota: nesta abordagem mais convencional, quando algum valor é omitido, recebemos como retorno um NaN (not-a-number). Isso acontece pois a referência do argumento omitido vai permanecer como undefined e ao tentar fazer uma operação de soma com um valor não numérico o JavaScript avalia a expressão com um NaN.

Para transformarmos a função ‘add’ em um Currying, primeiro temos que verificar a aridade da função; neste caso é 3. Depois teremos que aninhar funções que recebem apenas 1 parâmetro (funções unárias) até que os 3 valores tenham sido passados e a operação de soma possa ser realizada.

A versão utilizando Currying ficaria dessa forma:

Nota: caso você esteja se perguntando como a última função da cadeia continua tendo acesso aos parâmetros ‘a’ e ‘b’, isso é possível graças a Closure.

Aplicação Parcial

Ou Aplicação Parcial de Função é o processo de fixar – parcialmente aplicar uma função a – alguns dos argumentos, não todos, esperados por uma função, produzindo uma nova função de aridade menor na qual espera apenas os argumentos faltantes.

Para melhor entender essa definição, vamos criar uma função de multiplicação com aridade poliádica (mais de dois argumentos, lembra?).

E agora vamos criar uma função que possibilite parcialmente aplicar dois argumentos em nossa função genérica ‘multiply’, gerando uma nova função especializada em multiplicar por 4:

Nesse exemplo, podemos dizer que a função interna ‘partiallyApplied’ é uma Aplicação Parcial de ‘fn’, na qual, neste caso, faz referência à função ‘multiply’, pois tem “fixado” em si os argumentos providos na execução da função anterior ‘apply’.

Usando .bind(..)

Em JavaScript existe uma função da própria linguagem (built-in) chamada ‘bind’, que nos permite aplicar parcialmente os argumentos de uma função. Além disso, o ‘bind’ também tem a capacidade de definir o ‘this’ da função.

O primeiro parâmetro do ‘bind’ é o valor a ser definido como ‘this’. Como não temos a intenção de alterar o ‘this’ da função, vamos deixar esse argumento como ‘null’ e aplicar parcialmente os dois primeiros argumentos da função ‘multiply’, igual nos exemplos anteriores.

Assim temos o mesmo resultado da função dedicada ‘apply’ vista anteriormente.

Currying vs Aplicações Parciais

Como foi visto até agora, ambos Currying e Aplicações Parciais lidam com parâmetros de funções e como podemos parcialmente aplicar seus argumentos.

Você deve estar se perguntando: “Então Currying é também uma Aplicação Parcial?”

Acredito que tamanha confusão em torno do tema se dá devido a natural correlação feita entre o substantivo “Aplicação Parcial” e palavras como “parcialmente aplicar”, tal como aquela que utilizei propositalmente no parágrafo acima. Pensar desta forma faz sentido já que estamos provendo os argumentos de uma função de forma parcial, por partes. No entanto, as semelhanças acabam por aqui.

 

Contudo, podemos dizer que Currying permite a implementação de Aplicações Parciais, porém, como visto durante este artigo, possuem conceitos bem distintos. Seguem abaixo os principais deles:

1. Aplicações Parciais não se importam com o número de argumentos, já uma função com Currying espera estritamente que cada função de sua cadeia de funções receba apenas 1 argumento;

2. Um Currying, diferente da Aplicação Parcial, vai continuar retornando funções unárias até que todos os argumentos tenham sido especificados;

3. Não é possível aplicar Currying sobre um função que não tenha um valor fixo de argumentos. Caso contrário, nunca vamos saber quando finalizar a cadeia de funções. Já com Aplicações Parciais é totalmente viável.

 

Obrigado pela leitura e não deixe de comentar o que achou.

A Concrete é uma empresa da Accenture especializada no desenvolvimento ágil de produtos digitais. No capítulo de JavaScript nós trabalhamos com metas possíveis, porém desafiadoras. Fazemos parte de um time multidisciplinar, autogerenciado e auto-organizado e focamos no aprendizado contínuo, seguindo sempre práticas ágeis e lean de desenvolvimento. Nosso objetivo é transformar ideias em resultados concretos, com excelência! Quer fazer parte? Envie seu currículo para trabalheconosco@concrete.com.br.