Elemar DEV

Tecnologia e desenvolvimento .net

Functional Programming (Higher-Order Functions) com JavaScript

Olá pessoal. Tudo certo?!

No post anterior, mostrei como aplicar alguns princípios fundamentais (map e reduce) de programação funcional em JavaScript. Hoje, mostrocomo implementar Higher-order functions.

Live demo: http://users.cjb.net/livedemoelemarjr/higherorderfunctions.htm

Gist: https://gist.github.com/1363062

O que são Higher-Order Functions?!

Uma “higher-order function” recebe uma ou mais funções como parâmetro e devolve uma nova função como retorno.

Um exemplo simples

Comecemos a explicar os conceitos com um exemplo muito simples. Considere os testes abaixo:

test("isOdd/isEven", function () {
    ok(!isOdd(2), "isOdd, passing 2, returns false.");
    ok(isEven(2), "isEven, passing 2, returns true.");
});

Como você pode perceber, defini duas funçõesp para testar “par e impar”. Abaixo, está minha implementação:

var isEven = function (input) {
    return input % 2 === 0;
}

var not = function (f) {
    return function () {
        return !f.apply(this, arguments);
    };
}

var isOdd = not(isEven);

Reparem a forma pouco ortodoxa que implementamos a função isOdd. A função not é uma higher-order function (recebe e devolve uma função). Pegou a idéia?!

Um exemplo um pouco mais elaborado

Agora que já vimos um exemplo, de alto nível, vamos a algo um pouco mais elaborado. Comecemos com nosso teste:

test("isNegative/isZero/isPositive", function () {
    ok(isNegative(-1), "isNegative, passing -1, returns true.");
    ok(!isNegative(0), "isNegative, passing 0, returns false.");
    ok(!isNegative(1), "isNegative, passing 1, returns false.");
});

Agora, a implementação:

var isPositive = function (input) {
    return input > 0;
};

var isZero = function (input) { return input === 0; };

var and = function (f, g) {
    return function () {
        return f.apply(this, arguments) &&
            g.apply(this, arguments);
    };
};

var isNegative = and(not(isPositive), not(isZero));

A função and também é uma higher-order function.

Combinando funções

Considere o código abaixo:

var square = function (input) { return input * input };
var sum = function (a, b) { return a + b };
var compose = function (f, g) {
    return function () {
        return f.call(this, g.apply(this, arguments));
    };
};
var squareOfSum = compose(square, sum);

As funções square e sum executam operações muito simples. squareOfSum combina as duas funções. Veja o teste:

test("composing", function () {
    equals(squareOfSum(6, 3), 81, "squareOfSum, passing 6 and 3, returns 81.");
});

Combinando Higher-order functions com map

Para terminar, um exemplo que combina o post anterior com  o post de hoje. Considere:

 

var mapper = function (f) {
    return function (a) { return map(a, f); };
};

var incrementer = mapper(function (input) { return input + 1 });

Entendeu o que fizemos aqui?! Então entendeu os posts.

Smiley piscando

Testes:

image

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

Você está comentando usando sua conta WordPress.com. Sair / Mudar )

Imagem do Twitter

Você está comentando usando sua conta Twitter. Sair / Mudar )

Foto do Facebook

Você está comentando usando sua conta Facebook. Sair / Mudar )

Conectando a %s

Informação

Publicado às 13/11/2011 por em Post e marcado , , .

Estatísticas

  • 430,679 hits
%d bloggers like this: