BAM Weblog

Introducing bilby.js

Brian McKenna — 2012-09-09

While working on Roy, I’ve been coming up with some ideas and experiments on how to improve JavaScript code.

The most important is a safer form of ad-hoc polymorphism. Currently, JavaScript devs rely on duck typing and monkey patching to achieve polymorphism. My idea is to use an immutable multimethod environment, like so:

var env = λ.environment()
    .method('length', λ.isArray, function(a) {
        return a.length;
    })
    .method('length', λ.isString, function(s) {
        return s.length;
    })
    .property('empty', function(o) {
        return !this.length(o);
    });

env.empty([]) == true;
env.empty([1, 2, 3]) == false;

Extending the environment is easy. We can supply a function to be dispatched based on a predicate function (e.g. λ.isArray) or just a property on the environment object.

Another idea is to encode Option and Either types; and add implementations for common functional patterns like applicatives, functors, semigroups and monads. I’ve found this to be very useful while implementing the new Roy type system.

And I’ve been experimenting with some crazy operator overloading hacks. I’ve managed to implement a notation that looks like this:

// Monad:
λ.Do()(
    λ.some(1) >= function(x) {
        return x < 0 ? λ.none : λ.some(x + 2);
    }
).getOrElse(0) == 3;

// Semigroups:    
λ.Do()(
    λ.some(1) + λ.some(2)
).getOrElse(0) == 3;

I didn’t think it’d be possible but actually turns out to be quite a nice way to write complicated expressions. It’s a complete hack underneath but I don’t think it has shown through too much.

Anyway, as of today I’ve collected all of these ideas into a new library, bilby.js. Try it out and let me know what you think.

Please enable JavaScript to view the comments powered by Disqus.