Pular para o conteúdo principal

Curry with JS

Partial application and currying with Javascript

In the strict way, currying is the technique of transforming a function that takes multiple arguments (a tuple of arguments) to one function that receive only one. In such way, currying techniques allow transform one multi-parameter function in a chain of functions, each one with a single argument. Looks complicated? Blah.. it is not true.
In this little article, we are actually more interesting in partial applications. Let’s take the Mozilla Example for replace function in String. As we know, we can use a “replacer” function as paramenter for replace method in String object.
Let’s say that we want to split a String defined by a non-numerical part, a numerical part and finally a non-alphanumeric part. Here is how:
function replacer(match, p1, p2, p3, offset, string){
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
};
We can try it as usual…
var newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
So far so good. Let’s say now that the delimiter should change according with some conditions, e.g. locale specific.
function replacer(delimiter, match, p1, p2, p3, offset, string){
  return [p1, p2, p3].join(delimiter);
}
That’s bad. We cannot apply that replacer in regexp replace function. What can you do?
We want to have a partial application for that function. Take that!
function makeReplacer(delimiter) {
    return function replacer(match, p1, p2, p3, offset, string){
      return [p1, p2, p3].join(delimiter);
    }
}
So now, we can create a replacer for comma-separated-value:
var delimiter = ',';
var csvReplacer = makeReplacer(delimiter)
That constructor is so simple, so elementar that we could create a generic way to do that. Let’s create a curry function.
Function.prototype.curry = function() {
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function() { // new function
      return fn.apply(this, args.concat(
        Array.prototype.slice.call(arguments)));
    };
  };
How does the magic work? Closure!!! That dammit word is what defined the whole magic.
var fn = this;
var args = Array.prototype.slice.call(arguments);
First, arguments is a special object to access the parameters. However, arguments type is very similar to Array but it is not an Array. To use it in apply method we need to convert it to real Array. For that, we gonna use slice function. But slice function is a method defined on Array. Ok. Ok. Let’s use the slice function from Array replacing “this” object (within slice context) by “arguments” object. with the mighty call method…
Array.prototype.slice.call(arguments);
In that way, we have this and arguments saved on context. The Closure magic will keep that context (those local variables fn and args) within the context of new function. In that new function context, we also have a new values for this variable (now keeping the new function reference) and arguments (now the arguments of that function). So we can concat (add all elements) from arguments the to our args and we gonna have all arguments necessary for the original function.
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));};
So here we can rewrite the makeReplacer with curry… (because it is more spicy):
var delimiter = ',';
   var csvReplacer = replacer.curry(delimiter)

Comentários

Postagens mais visitadas deste blog

Um texto pós-moderno - better man

Espere olhando para as horas... são 4 horas. Tem que parar. Nesse tom melancólico, começa a modesta música "better man", uma balada pop composta por Eddie Vedder ainda na adolescência. A música é a ilustração perfeita da ironia. O próprio título é irônico, uma vez que em momento algum na música aparece um better man.

She lies and says she's in love with him, can't find a better man...

Irônico, não!? Para começar, com a personagem central da história, a mulher que aguarda tarde da noite seu esposo... Ela chega a treinar com o espelho o fim do relacionamento. E o que faz? Diz a negação do que queria dizer.

Vedder escreve músicas sobre sentimentos fortes. Sua relação com a mãe foi bastante complicada pelo o que descreve em suas canções. Na trilogia Mommy, Vedder descreve um homem perturbado com o relacionamento materno; a mãe mente para o filho sobre a identidade do pai, revela a verdade para o garoto na puberdade dizendo a ele como se parece com o verdadeiro pai e o leva …

Pequeno manual do ócio em terras alemãs

Pequeno manual do ócio em terras alemãsComo Lei alemã favorece aproveitadoras (e alguns aproveitadores que nunca tive o desprazer de conhecer)Há algumas vias pelas quais pessoas de países em desenvolvimento migram para países como a Alemanha.Por exemplo, é sabido que países desenvolvidos sofrem de escassez de mão-de-obra qualificada. Por esse motivo, países como a Alemanha dispõe vistos "especiais" para profissionais em demanda. Esse é o conceito do Blaukart (Blue Card) que na Alemanha se destina a profissionais salário anual seja superior a 55 mil euros ou 43 mil no caso de profissionais de áreas em alta demanda. Não há como recrutar essa mão-de-obra sem que a família desses profissionais também possa ser relocada. Então esses profissionais e seus familiares são relocados.Além de se qualificar para essas vagas em demanda, ou ser parte direta da família qualificada, outra via possível para a imigração para o território alemão é através do matrimônio. Como vivemos num mundo d…

O argumento anti-álcool

A lógica contra a produção do álcool é mais ou menos a seguinte:

Os produtores capitalistas, produtores do combustível de humanos e máquinas irão preferir vender combustível mais caro para os mais ricos do que comida barata para os mais pobres. Máquinas e homens irão competir por combustível... Mas enquanto os ricos terão dinheiro para comprar comida e combustível o que sobrará aos pobres!? Vale lembrar que não importa se a produção é de cana ou de milho, a competição é pela terra e não pelo grão. Ainda, mesmo que o país agrícola taxe o produtor de combustível de maneira diferenciada ao produtor de comida, o governo teria maiores dificuldades em repartir o "bolo", haja vista que os governos que temos não são as instituições mais eficientes e, além do que, a comida estará mais cara.

Ora, esquecem os "amigos" comunistas que a venda de biocombustível dará aos países agrícolas uma oportunidade ímpar de participar da economia mundial como protagonistas, e não meros figura…