Showing posts with label functional programming. Show all posts
Showing posts with label functional programming. Show all posts

Friday, May 27, 2011

The Beauty of Scheme

Bertrand Russell once noted that

Mathematics, rightly viewed, possesses not only truth, but supreme beauty—a beauty cold and austere, like that of sculpture, without appeal to any part of our weaker nature, without the gorgeous trappings of painting or music, yet sublimely pure, and capable of a stern perfection such as only the greatest art can show. The true spirit of delight, the exaltation, the sense of being more than Man, which is the touchstone of the highest excellence, is to be found in mathematics as surely as poetry.
I think much the same can be said of code, especially code written in certain languages. There is something so elegantly simple and beautiful about Scheme (and Racket), for example, that shares the same aesthetics of mathematics.

Thursday, November 18, 2010

Roll Your Own Map/Reduce in Javascript

I’ve been working on a very Javascript-heavy UI that allows the user to manipulate collections of objects. To ease the task of manipulation, I created a few methods on Array.prototype, which I rolled into a file I call iterable.js:

[sourcecode language="javascript"]
var Iterable = {
func: {
predicate: {
TRUE: function (x) { return true; }
}
}
};

Array.prototype.forEach = function (fn) {
for (var i = 0; i < this.length; i++)
fn(this[i]);
};

Array.prototype.filter = function (pred) {
var result = [];
this.forEach(function (x) {
if (pred(x))
result.push(x);
});

return result;
};

Array.prototype.distinct = function () {
var result = [];
this.forEach(function (x) {
if (!result.any(function (y) { return y == x; }))
result.push(x);
});

return result;
};

Array.prototype.any = function (pred) {
pred = pred || Iterable.func.predicate.TRUE;

for (var i = 0; i < this.length; i++)
if (pred(this[i]))
return true;

return false;
};

Array.prototype.indexOf = function (expr) {
if (!(expr instanceof Function))
expr = function (x) { return x == expr; };

for (var i = 0; i < this.length; i++)
if (expr(this[i]))
return i;

return -1;
};

Array.prototype.singleOrNull = function (pred) {
var filtered = this.filter(pred);
if (filtered.length == 0)
return null;
if (filtered.length > 1)
throw "More than one element returned.";

return filtered[0];
};

Array.prototype.map = function (fn) {
var mapped = [];
this.forEach(function (x) { mapped.push(fn(x)); });
return mapped;
};

Array.prototype.groupBy = function (sel) {
var groups = [];

this.forEach(function (x) {
var group = groups.singleOrNull(function (y) { return y.key == sel(x); });
if (!group)
groups.push({ key: sel(x), members: [x] });
else
group.members.push(x);
});

return groups;
};
[/sourcecode]

Note that this not particularly complete; for example, you’ll see that there is no implementation of a reduce function. It’s not here because I have not needed it in my project yet, nor am I likely to. But it would be easy to implement:

[sourcecode language="javascript"]
Array.prototype.reduce = function (fn) {
    if (this.length == 1)
        return this[0];
    return fn(this[0], this.slice(1).reduce(fn));
};
[/sourcecode]

Now, I’m aware of Underscore and others, so why did I do this? For two reasons, mainly: I only needed a subset of the functions that those libraries offer, and besides, it was fun.