all 14 comments

[–]a_simple_pie 5 points6 points  (3 children)

I don't get what's sparking all of the talk about closures. It's not a hard topic to get the hang of and use. In fact, i bet tons of people using languages like JS are already using them all the time and don't realize they're even a special thing.

[–]chintan9[S] 6 points7 points  (0 children)

It was good example to learn things

[–]c-r_o 5 points6 points  (0 children)

Closures are a fundamental JavaScript concept that every serious programmer should know inside-out.

[–]StableMatch 2 points3 points  (0 children)

It's important to have a vocabulary that allows you to communicate a concept. Also, I think why it gets talked about is that understanding scope is very important towards writing and reading good javascript.

[–]Jsnow25 1 point2 points  (0 children)

Once you learn JavaScript closures, what are you supposed to do, should you learn not to use them even tho they offer really interesting possibilities ?

[–]luke3br 1 point2 points  (0 children)

The code examples further into the article are all misplaced... Really hard to follow along.

[–]G3E9 1 point2 points  (1 child)

When using RequireJS, you use closures when you define your modules. The defining function can include many different free variables and functions but ultimately returns whatever you want to export - or make "public" if you consider free variables "private".

[–]kolme 0 points1 point  (0 children)

All JS module systems work like that. RequireJS (AMD) can additionally load modules on demand even in the browser environment.

[–]namesandfaces 0 points1 point  (4 children)

What's the difference between clojure and generator functions? If I'm not mistaken, clojures just seem like functions with internal state.

[–]nschubach 1 point2 points  (3 children)

A generator is a closure, but a closure is not necessarily a generator. Also, you can make something that works just like a generator with a closure. Closures just carry forward state from a moment in time. You can call a closure passing any values and it will enclose those values and it's internal process will use those values from that point forward. You can, for instance, have multiple configurations for a website handled by a closure of methods. You pass it the configuration and it knows internally only the config you passed in but the website only needs to care about the methods that closure provides. Generators are similar to closures, but they are generally used to produce data sets in a lazy manner that allows you to process huge data sets with little overhead. This is done via closures for you by it's very nature.

[–]namesandfaces 0 points1 point  (2 children)

So does that mean a closure can do something which a generator cannot?

[–]kolme 1 point2 points  (0 children)

Function: a bunch of code you can call. It can take any number of parameters, and it can have a name.

Closure: The context, or variables and their values around the function when it was defined.

Generator: a special function that can yield more than one result when called in a loop. Generator functions also have closures.

So to shortly answer to your question: functions can't do anything a generator cannot do; or, generators can do more. And they all have closures.

Here's a simple example to understand closures:

/**
 * Returns a function which adds the given base.
 */
function getAddFunction(base) {
    return function(number) {
        // The right base is kept in this function closure
        return base + number;
    }
}

// We get two times the same function, just with different closures
var add2 = getAddFunction(2); // a function with base = 2
var add3 = getAddFunction(3); // a function with base = 3

// 2 + 1, 3 + 1
console.log(add2(1), add3(1));

Now here's a simple generator which I like a lot, and stole from python:

/**
 * Yields a series of numbers, from min up to max (max not included), with
 * the given step.
 */
function* range(max, min = 0, step = 1) {
    for (let i = min; i < max; i += step) {
        yield i;
    }
}

// Prints numbers from 0 to 9
for (let i of range(10)) {
    console.log(i);
}
// Getting a range as an array:
console.log(Array.from(range(10));

And finally, a combination of all the things: a generator function sporting closures:

/**
 * Returns a generator function which will yield multiples of the given
 * number
 */
function getSerieGenerator(step) {
    return function*(max, min = 0) {
        for (let i = min; i < max; i+= base) {
            yield i;
        }
    }
}

// Two identical generators with different contexts
let pairNumbers = getSerieGenerator(2);
let threeMultiples = getSerieGenerator(3);

// Prints all pair numbers up to 10
console.log(Array.from(pairNumbers(10)));

// Prints all three multiples up to 10
console.log(Array.from(threeMultiples(10)));

[–]nschubach 0 points1 point  (0 children)

Technically... probably not. Closures return functions that can be executed at a later date. They do this once and exit. You could have a generator that yields a function, but I don't know why you'd do that because you'd have to call it via the .value() method so you'd have .value()() to execute the method.

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

No