<h2>Currying: A Arte de Transformar Funções</h2>
<p>Currying é uma técnica que transforma uma função que aceita múltiplos argumentos em uma sequência de funções que aceitam um argumento por vez. Quando você "currifica" uma função, cada chamada retorna uma nova função que espera pelo próximo argumento até que todos sejam fornecidos.</p>
<pre><code class="language-javascript">// Função normal
function somar(a, b, c) {
return a + b + c;
}
// Função currificada
function somarCurrificada(a) {
return function(b) {
return function(c) {
return a + b + c;
};
};
}
console.log(somarCurrificada(1)(2)(3)); // 6</code></pre>
<p>A vantagem real aparece quando você precisa reutilizar a função parcialmente. Currying permite que você crie versões especializadas sem duplicar código. Isso torna seu código mais modular e fácil de testar.</p>
<h3>Implementando um Curryificador Universal</h3>
<p>Criar um auxiliar que transforma qualquer função em sua versão currificada é essencial na prática. Aqui está uma implementação robusta:</p>
<pre><code class="language-javascript">function curry(fn) {
const arity = fn.length; // número de parâmetros esperados
return function curried(...args) {
if (args.length >= arity) {
return fn(...args);
}
return (...nextArgs) => curried(...args, ...nextArgs);
};
}
// Testando com uma função real
const multiplicar = (a, b, c) => a b c;
const multiplicarCurrificada = curry(multiplicar);
console.log(multiplicarCurrificada(2)(3)(4)); // 24
console.log(multiplicarCurrificada(2, 3)(4)); // 24
console.log(multiplicarCurrificada(2)(3, 4)); // 24</code></pre>
<p>Este padrão é poderoso porque permite flexibilidade: você pode chamar com um argumento ou vários de uma vez, e ainda assim obtém o resultado correto quando todos forem fornecidos.</p>
<h2>Partial Application: Fixando Argumentos Estrategicamente</h2>
<p>Enquanto currying força uma abordagem de um argumento por vez, partial application é mais pragmática: você fixa alguns argumentos e deixa outros para depois. Não é tudo ou nada, mas uma especialização estratégica.</p>
<pre><code class="language-javascript">// Partial application manual
function dividir(a, b) {
return a / b;
}
// Fixar o divisor como 2
function dividirPorDois(a) {
return dividir(a, 2);
}
console.log(dividirPorDois(10)); // 5
// Usando bind (nativo do JavaScript)
const dividirPorTres = dividir.bind(null, 30);
console.log(dividirPorTres(2)); // 15 (30 / 2)</code></pre>
<p>A diferença sutil mas importante: currying retorna sempre uma função até ter todos os argumentos; partial application retorna o resultado assim que houver argumentos suficientes para executar.</p>
<h3>Criando um Helper de Partial Application</h3>
<p>Para maior controle e legibilidade, implemente um utilitário dedicado:</p>
<pre><code class="language-javascript">function partial(fn, ...fixedArgs) {
return function(...restArgs) {
return fn(...fixedArgs, ...restArgs);
};
}
// Aplicação prática
const lerquivo = (encoding, filePath) => Lendo ${filePath} com encoding ${encoding};
const lerUTF8 = partial(lerquivo, 'utf-8');
const lerLatin1 = partial(lerquivo, 'latin1');
console.log(lerUTF8('/arquivo.txt')); // Lendo /arquivo.txt com encoding utf-8
console.log(lerLatin1('/arquivo.txt')); // Lendo /arquivo.txt com encoding latin1</code></pre>
<p>Partial application é especialmente útil em composição de funções e callbacks, onde você precisa adaptar uma função existente sem reescrevê-la completamente.</p>
<h2>Casos de Uso Reais no Dia a Dia</h2>
<p>Na prática, essas técnicas resolvem problemas concretos. Considere um cenário comum: processar dados com funções especializadas.</p>
<pre><code class="language-javascript">// Exemplo: Processador de eventos com currying
const registrarLog = curry((nivel, modulo, mensagem) => {
console.log([${nivel}] [${modulo}] ${mensagem});
});
const logErro = registrarLog('ERRO');
const logErroAuth = logErro('AUTH');
const logErroDatabase = logErro('DATABASE');
logErroAuth('Falha na autenticação'); // [ERRO] [AUTH] Falha na autenticação
logErroDatabase('Conexão perdida'); // [ERRO] [DATABASE] Conexão perdida
// Exemplo: Validação com partial application
const validarEmail = (pattern, valor) => pattern.test(valor);
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const validarEmailPadrao = partial(validarEmail, emailRegex);
console.log(validarEmailPadrao('user@example.com')); // true
console.log(validarEmailPadrao('invalid-email')); // false</code></pre>
<p>Esses padrões simplificam a criação de pipelines de transformação de dados, frameworks que precisam de callbacks customizados, e sistemas que lidam com configurações variáveis. Eles reduzem repetição de código e aumentam a reutilização.</p>
<h2>Conclusão</h2>
<p>Currying e partial application são ferramentas poderosas da programação funcional que transformam como você escreve JavaScript. <strong>Primeiro ponto</strong>: currying força uma disciplina de um argumento por vez, resultando em funções altamente reutilizáveis e componíveis. <strong>Segundo ponto</strong>: partial application oferece flexibilidade pragmática, permitindo especializar funções sem a rigidez do currying. <strong>Terceiro ponto</strong>: ambas reduzem duplicação de código e facilitam testes, sendo especialmente valiosas em arquiteturas que usam composition e higher-order functions.</p>
<p>Domine essas técnicas e você terá um código mais limpo, testável e verdadeiramente funcional.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" target="_blank" rel="noopener noreferrer">MDN Web Docs - Function</a></li>
<li><a href="https://javascript.info/currying-partials" target="_blank" rel="noopener noreferrer">JavaScript.info - Currying</a></li>
<li><a href="https://github.com/getify/You-Dont-Know-JS" target="_blank" rel="noopener noreferrer">You Don't Know JS Yet - Functional Programming</a></li>
<li><a href="https://lodash.com/docs/#curry" target="_blank" rel="noopener noreferrer">Lodash - curry e partial</a></li>
<li><a href="https://eloquentjavascript.net/05_higher_order.html" target="_blank" rel="noopener noreferrer">Eloquent JavaScript - Higher-order Functions</a></li>
</ul>