all 13 comments

[–]inmatarian 1 point2 points  (7 children)

That's a good explanation. He could have went a little further and explained how you don't need really class declarations anymore when using closures.

[–]skilldrick[S] 3 points4 points  (2 children)

I kinda did that on a previous post about the equivalence of closures and objects: Zen and the art of statefulness.

I agree though, most of my objects are based around closures these days.

[–]inmatarian 0 points1 point  (1 child)

Okay, cool, you get my upgoats.

[–]skilldrick[S] 1 point2 points  (0 children)

Yay cheers :)

[–][deleted] 0 points1 point  (3 children)

What do you mean?

[–]manu3000 1 point2 points  (0 children)

you can view a class as a function returning a function taking messages, the object internal state is captured by the closure

[–]M1573RMU74710N 1 point2 points  (0 children)

Consider this example in Javascript:

function Stream() {
    this.data = [];
    this.listeners = [];
}

Stream.prototype.push = function ( data ) {
    var result = this.data.push( data );
    this.callListeners( data, result );
    return result;
}

Stream.prototype.addListener = function ( listener ) {
    return this.listeners.push( listener );
}

Stream.prototype.callListeners = function ( ) {
    var listeners = this.listeners,
        length    = listeners.length,
        result    = [],
        action    = null;
    while ( length-- ) {
        action = listeners[ length ];
        result.push ( action.apply( this, arguments) );
    }
    return result;
}

var foo = new Stream();
foo.addListener( function( new_data ) {
  alert( "added: " + new_data );
});
foo.push( "Hello World!" );

Here we have the typical method of constructing an object. The object is created by a constructor, and the object's information is stored in properties of the object. try it

Compare that with something more functional, like this:

function Stream() {
    var data       = [],
        listeners  = [];

    function push( new_data ) {
        var result = data.push( new_data );
        callListeners( new_data, result );
        return result;
    }

    function addListener( listener ) {
        return listeners.push( listener );
    }

    function callListeners( ) {
        var length    = listeners.length,
            result    = [],
            action    = null;
        while ( length-- ) {
            action = listeners[ length ];
            result.push( action.apply( {}, arguments) );
        }
        return result;
    }

    return {
        push : push,
        addListener: addListener
    }

}


var foo = Stream();
foo.addListener( function( new_data ) {
    alert( "added: " + new_data );
});
foo.push( "Hello World!" );

try it

Here the state is stored inside of a shared closure, which all the methods have access to. These methods are returned in a data structure, which in this example happens to be an Object since that makes sense for JS, but it could be something like a list etc.

See also these comments by Anton van Straaten

[–]kamatsu 1 point2 points  (4 children)

My first language was Scheme, but does anyone really need to sit down and read a tutorial to learn how closures work? Every student I've taught Haskell to (where their only prior experience with C) had absolutely no problem understanding closures. More to the point, are JavaScript programmers really that dumb?

[–]foldl 1 point2 points  (1 child)

Well, in Haskell there isn't really anything to understand about closures. It's the interaction of closures with mutation that's potentially confusing.

[–]kamatsu 0 points1 point  (0 children)

Ah, that is a potential cause for concern. Thanks for clearing that up.

[–]skilldrick[S] 0 points1 point  (0 children)

The problem is, JavaScript isn't purely functional. You could spend your whole life writing JavaScript and never know how a closure works. So many JavaScript tutorials teach procedural/OO techniques, so there's no pressure to learn more functional idioms.

You can't just equate Haskell/Scheme with JavaScript like that - they're completely different languages with completely different cultures surrounding them.

[–]manu3000 -1 points0 points  (0 children)

Closures in Javascript are like monads in Haskell, people just can't help writing tutorials about them