Archive

Archive for November, 2010

A brief introduction to closures

November 22nd, 2010 15 comments

In this post, I’m going to attempt to explain what closures are and how to use them. Many modern (and some not-so-modern) programming languages contain support for closures, but for the purposes of this article I’m going to be using JavaScript. I’ve chosen JavaScript for a few reasons:

  • Ubiquity: If you have a web browser then you have a JavaScript interpreter
  • Simplicity: JavaScript is conceptually a fairly simple language (especially if you limit yourself to its Good Parts), compared to other dynamic scripting languages such as Python and Ruby
  • Familiarity: If you’ve used any of the C family of languages (e.g. C++, Java or C#) then JavaScript will look fairly familiar.

There may be some differences between languages with the mechanics, but deep down, closures are the same across all languages which allow them, so if you can understand the concept in JavaScript, you’ll understand it in any capable language.

Functional programming

Before I can get onto closures, I need to give a very brief introduction to functional programming.

Functional programming is all about functions (I doubt that comes as much of a surprise). In a language that surports functional programming, functions are generally first-class objects. That means they can be assigned to variables, stored in data structures, passed into functions and returned from functions.

In JavaScript, it’s important to distinguish between referencing a function and calling a function. To reference a function, just use the function name. To call a function, append parentheses (with optional arguments). Here’s an example:

function f() {
    alert('f called!');
}

f(); // calls f
var x = f; // f is a reference to the function, and now x is too
x(); // calls f (or x - they're the same thing)

It’s also possible to create anonymous functions in JavaScript (aka lambdas). If you want to create an anonymous function, leave out the name:

function () {
    alert('I have no name');
}

Another name for an anonymous function is a function literal. If you imagine it like a string literal you’ll see it’s an expression just like any other literal, and so it can be assigned to a variable:

var str = "string"; //string literal
var arr = [1, 2, 3]; //array literal
var obj = { 'JS': 1,
            'is': 2,
            'awesome': 3 }; //object literal
var f = function () {
    alert("I've been assigned to f");
}; //function literal

Note that there is very little difference between assigning an anonymous function to a variable called f and defining a function called f – the end result of both is a function that can be referred to by the name f, and can be called with f().

Another capability of functional languages is the ability to nest functions. It’s perfectly valid in JavaScript to define one function within another. Here’s another example:

function outer() {
    function inner() {
        alert('In ur function');
    }
    inner(); // we can call inner here as it is defined in outer's scope
}
inner(); // Error - but not here - inner is not defined in this scope

It’s this ability, coupled with the first-class nature of functions, that enables closures.

A real-life closure

A closure is a function with access to variables in its containing scope (the function “closes over” the variables). The thing that can be tricky to wrap your head round is that the inner function still has access to the outer function’s variables after the outer function has returned. Here’s an example:

function outer() {
    var counter = 0;
    function inner() {
        alert(counter);
        counter++;
    }
    return inner;
}

var x = outer(); // As we're calling outer here, x is a reference to inner 
x(); // alerts 0
x(); // alerts 1
x(); // alerts 2

In this code, outer is called once, and returns inner. x is a reference to inner. Because inner is a closure, it has access to outer‘s local variable, counter. Even though outer has returned, inner still has access to outer‘s variables. Be careful though – if outer were called again, we’d get a new version of inner. To continue the previous example:

var y = outer(); // Call outer again
y(); // alerts 0 - this is a different closure to the previous one.

The closure has access to any arguments in the containing scope as well:

function outer(x) {
    function inner() {
        alert(x);
    }
    return inner;
}

var func = outer(5);
func(); //alerts 5 - inner has access to the argument

A more advanced example

You should now know enough about the basics of closures to understand a more complex example. Here’s a way to give a JavaScript object private variables:

function CatMaker(name) {
    var age = 10;

    //construct an object on the fly with three methods.
    //All methods have access to age, but age cannot be
    //directly accessed outside of this function.
    return { 
        "sayHello": function () { //first method
            alert("Miaow");
        },
        "getAge": function (inCatYears) { //second method
            if (inCatYears) {
                return age * 7;
            }
            else {
                return age;
            }
        },
        "makeOlder": function () { //third method
            age++;
        }
    };
}

var mycat = CatMaker('Snuffles');
mycat.getAge(true); //returns 70
mycat.makeOlder();
mycat.getAge(true); //returns 77

The ONLY way to make changes to the private variable age is through the method makeOlder. All the methods share the same age variable, because they were all made in the same call of CatMaker. If we called CatMaker again to produce a new cat, it would have its own age variable.

The infamous lambda-in-a-loop problem

Consider the following example:

function attachListeners() {
    for (var i = 0; i < 10; i++) {
        $('#id-' + i).click(function () {
            alert("I am element number " + i);
        });
    }
}

It’s using jQuery. To understand this example you’ll need to know a tiny amount of how jQuery works. jQuery creates a global function called jQuery, aliased to $. The jQuery function takes (among other things) a CSS selector. It returns a jQuery object representing the HTML elements matching that selector. A click handler can be added by calling .click() on the returned object. .click() takes a function to be executed when the matched elements are clicked on. $('#myid').click(function () { alert('hello'); }); will show an alert when the HTML element with an id of ‘myid’ is clicked on.

The example selects 10 elements on the page, with the ids id-0, id-2 up to id-9. Each time round the loop, a new click handler is created. When you click on these elements, an alert box comes up. Some would think that each click handler has its own version of i but you know better. All the click handlers share the same i. Because of the way the for loop works, this value is one past the end of the loop, i.e. 10. So each element proudly announces that it is element number 10, which is clearly incorrect.

The problem here is that although a new closure is being produced each time round the loop, each closure shares the same environment, so i in each closure is the same i as in all the others.

Take a look at a working demonstration of the above code using jsFiddle. Have a play with it so you can get a feel for what’s going on.

The only way around this is to use another function:

function addOneListener(i) { //Each time i is bound to a different value
    $('#id-' + i).click(function () {
        alert("I am element number " + i);
    });
}

function addEventListeners() {
    for (var i = 0; i < 10; i++) {
        addOneListener(i); 
    }
}

Here’s the above as a fiddle. emehrkay in the comments has an alternative implementation of the above using raw DOM methods – it’s often useful to see different ways of achieving the same thing.

The key to understanding the new example is that every time addOneListener is called, a new closure is produced, and each of these closures has a different i. When you start using closures in JavaScript, this will bite you eventually, so beware. It’s such a common issue that bobince of HTML-parsing regex fame put it at number three in his list of common questions on Stack Overflow:

At number three it’s a new entry for “Why is my (Python, JavaScript, …) function getting the same value of the variable every time around the loop?”, by Clint Forloop and the Closures

Vim exercises for the beginner

November 8th, 2010 1 comment

Vim comes with a great little thing called vimtutor. This walks you through the basic Vim commands, so you’re able to get up and running. Each lesson has a small exercise to try out the command or commands taught.

Going through these lessons, I wished that there were more exercises for each lesson, so the key strokes would sink in better. So, without further ado …

Introducing Vim exercises!

I’ve only done a few lessons so far, but eventually I’d like to do exercises for all the lessons in vimtutor. They’re designed for the complete newbie to Vim, but would hopefully be useful to anyone learning Vim.

The exercises are available on github, but if you’re not using git (and if not, why not?!) you can download the file directly.

Here’s a sneak-peek:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lesson 1.1: Moving the cursor
Instructions: Follow the line around the screen using h, j, k and l.
|             Hint: if you accidentally start typing text, press Esc          
|       .-------.   to leave insert mode and u to undo any changes.           
|       |       |                                                             
\_______/       |                                                             
                |                                                             
                |                                                             
                \____.                                                        
                     |    .-----------------.                                 
                     |    |                 |                                 
           .---------+----+----.            |                                 
           \_________/    |    |            |                                 
                          |    |            |                                 
                          |    |            |                                 
                          |    \________.   \________ Well done! Now scroll   
                          |             |             down to lesson 1.3      
                          |             |             with j.                 
                          |             |                                     
                          \_____________/                                     



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lession 1.3: Text editing - deletion
Instructions: Correct the lines of text below by deleting the
unneccesary characters with  x . Hint: use 0 to return to the left.

Faar ouxt inn trhe unchttarteed bakckwataers oof the unfashionable end of the 
Weeestern sSpiral arrm ohf thze Gallaxy lies ae sm*all unregarded yellow syun.

Iti ijs aaa trufth universalllly acknowledgegeged, that a sxingle manr iin 
possessibon of aw gopod fort^une muost bee in wantxxx of a) wife.&&

Int waes lourvve at first sighght.. The feeirst time Yossarian sa9w th$e 
chaplain heee fell maaadly in lov*ve with himmmm. 

Aaas Gregor Samsa awokke onne moorning frrom uneeasy ddreams hhe founnd 
himmself trransformed inn hiis bbed intoo a giiigantic insecct.

It was  a bright cold day in  April, and the clocks  were striking   thirteen.

Twwo householllds, bothe alikee inf dignityyyy,
IIIn fair% Verrrrona, whereq wiie lay# ou987r sc"ene,
Frrom ++ancient grudddge brrrreak tto #new mutiny,,,
Where7 ciiviil blo*od mak^es civil h=ands uncclean.
Categories: Linux, Programming Tags: ,

Why classes are confusing in Ruby

November 8th, 2010 1 comment

I wrote before about how Object and Class are confusing in Ruby. I think I know what’s so confusing about it now.

In most other OO languages there are two concepts, objects and classes. Objects are instances of classes, and classes can be subclasses of other classes. Basically, each object or class has what could be described as a pointer. An object has a pointer to its class, and a class has a pointer to it’s superclass. In Java, where every class inherits directly or indirectly from Object, there is a clear line from each individual object to the Object class, via the object’s class and its class’s superclasses. Let’s take Bob, an employee:

      class          superclass      superclass
bob    ->    Employee    ->    Person    ->    Object

There’s a clear line from bob to Object, via bob’s class, and his class’s superclasses.

In Ruby, there’s still this line, but because classes are objects as well, there’s an extra line. There isn’t one pointer – there are two. Each class has a class and it has a superclass. That’s how you get to the point where Class is_a Object, and Object is an instance_of Class. Here’s some beautiful ascii art to illustrate:

  Class -------> Module -------> Object
    ^
    |            Class --------> Module -------> Object
    |              ^
    |              |
  Class -------> Module -------> Object
    ^
    |            Class --------> Module -------> Object
    |              ^
    |              |
Employee ------> Person -------> Object
    ^
    |              
   bob

Every vertical pointer describes an instance_of relationship. Every horizontal pointer describes an is_a relationship. I haven’t drawn all the instance_of relationships of the classes, because if I did I’d be drawing an infinite tree of Class, Module and Object nodes, and I don’t have time tonight to do that.

That’s what makes Object and Class so confusing in Ruby. In most other OO languages that use Object as the overall base class, there is a straight line between an object and Object (with multiple inheritance you can get diamonds, but it all gets back to the one Object eventually). With Ruby, if you follow all the relationships you end up with an infinite tree.

Of course, this is only because I’m insisting on following all the instance_of relationships. In most circumstances you can just forget that classes are objects, and only follow the is_a relationships. The only instance_of relationships that usually matter are between non-class objects and their classes. But if you follow the rabbit hole, you’ll find just how deep it goes …


I’ve now very much clarified my thinking on Ruby classes. See: Understanding the Ruby object model.

Categories: Programming Tags: ,

Something confusing about Ruby: Object and Class

November 8th, 2010 1 comment

In Ruby, everything is an object, every object has a class, and all classes inherit from Object. Three very simple statements.

Here’s where it gets complicated:

Classes are objects

If a class is an object, then it has to have a class. That class is Class. Here’s an example

class Example; end  #an empty class
Example.class  # => Class

So, if Class is a class, what is its class?

Class.class  #=> Class

Ok, fine. What is Object‘s class?

Object.class  #=> Class

No surprises there.

So far we’ve seen that Example, Class and Object are all instances of the Class class. That’s one part of OO – objects are instances of classes. In Ruby, where everything is an object, then even classes are instances of classes. And the the class of a class is Class.

The other part of OO is inheritance. Classes inherit from other classes. I’ve already stated that everything inherits from Object (either directly or indirectly). Let’s test that:

Example.superclass  # => Object
Object.superclass   # => nil (it's not turtles all the way down)
Class.superclass    # => Module
Module.superclass   # => Object

So, every class inherits from Object except for Object, which doesn’t inherit from anything.

Where does this lead then? Well, have a gander:

Object.instance_of? Class  # => true
Class.is_a? Object  # => true

Object is an “instance” of Class, but Class “is” an Object.

Conclusion

Ruby really does take this “everything is an object” thing seriously. Wow. And my brain hurts.

Categories: Programming Tags: ,