Announcing Pocco

June 29th, 2010

Out of respect for the Pocoo team, I have renamed Pocco to Pycco to alleviate the ambiguities created from such similar names. Pocoo, thanks for creating Pygments and all the other cool projects you guys do! Here is Pycco's new github project page.

Pocco is a Python port of Jeremy Ashkenas' Docco. Pocco, like Docco before it, generates literate-programming-style documentation from your source files.

To see it in action, simply check out the github project page, which is the result of running pocco on itself.

To install, simply

git clone git://github.com/fitzgen/pocco.git
cd pocco/
sudo python setup.py install

Bug reports welcome!

View Comments


Yet Another Lisp

June 25th, 2010

I couldn't help it.

Between my current PL course and reading Lisp in Small Pieces off-and-on, I had to start writing my own Lisp again. I have named it Magritte, after René Magritte. So far just the basics are working. Pattern matching and destructuring, but no guards yet. Lambdas are a go, but the lexical scope is a little buggy still. No macros yet.

Here is the famed Y Combinator, in Magritte.

magritte> (defn (Y X)
            ((fn (procedure)
               (X (fn (arg) ((procedure procedure) arg))))
             (fn (procedure)
               (X (fn (arg) ((procedure procedure) arg))))))
(((X) . #<CLOSURE # {BD7D315}>))
magritte> (def fact (Y (fn (f) (fn (n)
                                 (if (eq? n 0)
                                     1
                                   (* n (f (- n 1))))))))
#<CLOSURE (LAMBDA (VALUES &KEY (BINDINGS NIL))) {BA383E5}>
magritte> (fact 3)
6
magritte> (fact 8)
40320

And here is a pretty typical definition of map, using pattern matching and destructuring.

magritte> (defn (map f ()) ())
(((F NIL) . #<CLOSURE # {B83C1D5}>))
magritte> (defn (map f (h . t)) (cons (f h) (map f t)))
(((F (H . T)) . #<CLOSURE # {BB4C0E5}>)
 ((F NIL) . #<CLOSURE # {B83C1D5}>))
magritte> (map (fn (x) (* x x)) '(1 2 3 4 5 6 7 8 9))
(1 4 9 16 25 36 49 64 81)

Currently, Magritte is written in Common Lisp. My plan is to get the interpreter to a decent level of quality, then write a Magritte -> Common Lisp compiler, in Magritte. Then we'll really be having some fun!

View Comments


Recent Happenings: All Play and No Work

June 21st, 2010

What have I been doing lately? Quite a few things.

I released Wu.js, which is a lazy, functional library that ain't nuthin' ta fuck wit. The Hacker News community responded positively and sent me a bunch of traffic. Then I wrote a guest blog on Wu.js for internet buddy Angus Croll. It's about one of the many Higher Order Functions in the library, wu.autoCurry.

Then, amazingly, I found out that there iswas no Javascript library for the GitHub API, so I started one. Right now the repositories, users, issues, commits, and authentication APIs are implemented. Still need to get down and dirty with objects, gists, and the network. And documentation. For the most part, if you read the GitHub API documentation it is pretty easy to translate directly to my Javascript code. For example,

$ curl http://github.com/api/v2/json/user/show/defunkt
$ curl http://github.com/api/v2/json/repos/show/schacon/grit

becomes

gh.user("defunkt").show(function (data) { /*...*/ });
gh.repo("schacon", "grit").show(function (data) { /*...*/ });

etc.

At work we finally made the big switch from git-svn to pure git. I have been learning a ton more about git in the week that this has taken place. Its amazing how large the differences between my own personal projects' and our team at work's use of git are. Not in a bad way, though; it has been really educational.

Originally, we were trying to host our repositories via gitosis, but gitosis got in our way. It did too much, at the expense of flexibility. I ended up writing a couple little bash scripts and a post-receive hook that together handle all of our needs for git hosting. The project is named mini-meta-git, and is on GitHub. I will quote myself from the README, to give you an idea of what functionality mini-meta-git provides:

Basically, all this adds on top of a normal git server is authentication (NOT authorization or permissions) via the mini-meta-admin repo, which is just a repo containing ssh public keys. It let's you take care of the rest without getting in your way.

Really simple, but that's all I want.

A couple months ago I gave a presentation to the Whatcom Python Users' group on class-based views and Django. Since then, the generic, class-based views thread on the Django-developers mailing list has been buzzing. Django 1.3 is the target. No one can seem to agree on what the best implementation would be, but Ben Firshman wrote a bunch of code at the DjangoConEU sprints, and I modified it to use the __new__ approach, rather than make a copy of self. The verdict is still out on which way this will end up going.

And speaking of Django, I released version 0.3.2 of my semi-port of a small subset of the Django Templating Language to Javascript, Tempest. The new release exposes a couple handy ex-private functions to developers. It should make developing custom tags a lot easier. Also, this was the first time I used the Google Closure Compiler on Tempest, so the minified version has quite a smaller footprint than the ones before it. Thanks to GroteBozeWolf for getting on my case about this and making sure I took care of this.

And last but not least, as you can probably tell if you aren't reading this from your feed reader, I spent all day today redesigning this site. I am no CSS master, but Blueprint CSS framework is a lot of help.

That's all, over and out.

View Comments


Arguments.callee considered extraneous

June 2nd, 2010

There is a fairly well known method anonymous recursion in Javascript. Every Javascript function has access to an implicit arguments object, and attached to that is the the callee property which holds the function being currently being invoked.

You might see arguments.callee used in a situation similar to this:

var items = [1,2,3,4,5,6,7];

// As we process the items, use setTimeout to give the UI thread time to update.
setTimeout(function () {
    if (items.length === 0) {
        finish();
    }
    else {
        heavyProcessing(items.shift());
        setTimeout(arguments.callee, 20); // Recur via arguments.callee
    }
}, 20);

However, there is a more elegant solution: function expressions with a name that is only visible from within their own scope.

var factorialOf5 = (function factorial(n) {
    return n === 0 ? 1 : n * factorial(n - 1);
}(5));
console.log(factorialOf5); // 120
console.log(factorial); // ReferenceError: factorial is not defined

To understand why this works, it is important to understand that Javascript has two different forms for creating functions which (perhaps frustratingly) look very similar.

  1. Function declarations introduce a new, named function to the current scope. These are statements by themselves and cannot be combined with other expressions.

    function name( [param*] ) {
        [statement*]
    }

    Note that declarations really perform two operations: one, create a new function; two, bind that new function to name in the current scope.

  2. Function expressions simply create a new function and return it. A function expression can be used as an argument to another function (think callbacks), assigned to variables, or invoked immediately.

    function [name] ( [param*] ) {
        [statement*]
    }

    Name is optional in function expressions, without it the function is anonymous, with it the only the function itself can refer to that name.

In the following example, foo, bar, and arguments.callee all provide a medium to recursion inside the function, however only foo is accessible from outside the function.

var foo = function bar() {
    return foo === bar
        && foo === arguments.callee
        && bar === arguments.callee;
}

foo() // true
bar // ReferenceError: bar is not defined

Not only does using a named function expression provide cleaner code than accessing arguments.callee, it helps you out when it is time to profile or debug your code. A stack trace consisting of ten "anonymous function"s and line numbers is nowhere near as helpful as the named functions will be.

View Comments


Javascript, "bind", and "this"

May 20th, 2010

All javascript functions have access to an implicit argument this. By default, this refers to the global window object, but when a function is bound to an object as a method, this refers to the object.

function testThis() {
    return this === window;
}

testThis(); // true

var obj = {
    testThis: function () {
        return this === obj;
    }
};

obj.testThis(); // true

However, it is possible to dynamically call functions with a new value bound to this by using the Function.prototype.call and Function.prototype.apply methods. Call takes arguments individually, while apply takes them as an array.

function alertMsg(message) {
    return alert(this + message);
}

alertMessage.call("Hello, ", "World!"); // alerts "Hello, World!"

alertMessage.apply("Goodbye, ", ["cruel world!"]) // alerts "Goodbye, cruel world!"

But, often it is helpful to permanently bind the scope of this for a function. This technique was first pioneered by Prototype.js. At its most basic, the function bind will take two arguments: the first is an object that will be bound as this for the function that is the second argument.

// Useful for making the "arguments" object a true array and also for creating a
// copy of an existing array.
function toArray(obj) {
    return Array.prototype.slice.call(obj);
}

// Bind in its simplest form

function bind(scope, fn) {
    return function () {
        return fn.apply(scope, toArray(arguments));
    };
}

// Examples

var dog = {
    noise: "Ruff!"
};
var truck = {
    noise: "Honk!"
};

function makeNoise() {
    return this.noise;
}

makeNoise(); // undefined
bind(dog, makeNoise)(); // "Ruff!"
bind(truck, makeNoise)(); // "Honk!"

var noise = "<Douglas Crockford puking in disgust>";
makeNoise(); // "<Douglas Crockford puking in disgust>"

It is also possible to write bind such that it curries your function as well. For a more detailed description of currying in Javascript, check out this article by Angus Croll.

// Bind w/ currying

function bind(scope, fn /*, variadic args to curry */) {
    var args = Array.prototype.slice.call(arguments, 2);
    return function () {
        return fn.apply(scope, args.concat(toArray(arguments)));
    };
}

// Bind w/ currying examples

function convert(ratio, input) {
    return (ratio * input).toFixed(1) + " " + this.unit;
};

var pounds = {
    unit : "lbs"
};
var kilometers = {
    unit: "km"
};

var kilosToPounds = bind(pounds, convert, 2.2);
var milesToKilometers = bind(kilometers, convert, 1.62);

kilosToPounds(2.5); // "5.5 lbs"
milesToKilometers(13); // "21.1 km"

It is possible to implement somewhat Pythonic iterators using a combination of bind and Array.prototype.shift. Iterators provide a cleaner, more elegant API for looping over the items in an array than the typical for-loop could.

// A specific iterator

var item,
    iterZeroToNine = bind([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                          Array.prototype.shift);

// Log each of the integers in the range 0 - 9
while (item = iterZeroToNine()) {
    console.log(item);
}

// A generic iterator generator

function iter(arr) {
    var items = toArray(arr); // Also makes a copy
    return bind(items, Array.prototype.shift);
}

The synthesis of closures and bind provides a powerful tool for abstracting and hiding implementation details. Consider the following code, which implements a rudimentary stack data type for DOM nodes.

function createDOMStack(selector) {
    var elts = toArray(document.querySelectorAll(selector)),
        pushToElts = bind(elts, Array.prototype.push);

    return {
        push: function (item) {
            if (item instanceof HTMLElement)
                pushToElts(item);
            else
                throw new Error("Can only push DOM elements to this stack!");
        },
        pop: bind(elts, Array.prototype.pop)
    };
}

Using createDOMStack

Its also worth noting that a native version of bind with currying will be available as Function.prototype.bind once ECMAScript 5 is widely implemented by the browser vendors. For more information see the WebKit ticket, and Mozilla ticket.

View Comments


« Older Entries

Newer Entries »

Recent Entries


setTimeout Patterns in JavaScript

On August 10th, 2010


ParenScript is an Acceptable Lisp

On August 2nd, 2010


TryParenScript.com

On July 23rd, 2010


In response to "A JavaScript Function Guard"

On July 19th, 2010


My Notes from John Resig's "jQuery Hack Day" Talk

On July 5th, 2010


Announcing Pocco

On June 29th, 2010


Yet Another Lisp

On June 25th, 2010


Recent Happenings: All Play and No Work

On June 21st, 2010


Arguments.callee considered extraneous

On June 2nd, 2010


Javascript, "bind", and "this"

On May 20th, 2010


Creative Commons License

Fork me on GitHub