Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use closure? [closed]

I have seen samples of closure from - What is a 'Closure'?

Can anyone provide simple example of when to use closure?

Specifically, scenarios in which closure makes sense?

Lets assume that the language doesn't have closure support, how would one still achieve similar thing?

Not to offend anyone, please post code samples in a language like c#, python, javascript, ruby etc.
I am sorry, I do not understand functional languages yet.

like image 818
shahkalpesh Avatar asked Nov 02 '08 07:11

shahkalpesh


People also ask

When should closures be used?

Closures are frequently used in JavaScript for object data privacy, in event handlers and callback functions, and in partial applications, currying, and other functional programming patterns.

Why would you use a closure?

Closures are useful because they let you associate data (the lexical environment) with a function that operates on that data. This has obvious parallels to object-oriented programming, where objects allow you to associate data (the object's properties) with one or more methods.

What is closure and when should you use it?

A closure is created when the inner function is somehow made available to any scope outside the outer function. In the code above, the name variable of the outer function is accessible to the inner functions, and there is no other way to access the inner variables except through the inner functions.

Why are closures called closures?

A closure is a function and its scope assigned to (or used as) a variable. Thus, the name closure: the scope and the function is enclosed and used just like any other entity.


2 Answers

Closures are simply great tools. When to use them? Any time you like... As has already been said, the alternative is to write a class; for example, pre C# 2.0, creating a parameterised thread was a real struggle. With C# 2.0 you don't even need the `ParameterizedThreadStart' you just do:

string name = // blah int value = // blah new Thread((ThreadStart)delegate { DoWork(name, value);}); // or inline if short 

Compare that to creating a class with a name and value

Or likewise with searching for a list (using a lambda this time):

Person person = list.Find(x=>x.Age > minAge && x.Region == region); 

Again - the alternative would be to write a class with two properties and a method:

internal sealed class PersonFinder {     public PersonFinder(int minAge, string region)     {         this.minAge = minAge;         this.region = region;     }     private readonly int minAge;     private readonly string region;     public bool IsMatch(Person person)     {         return person.Age > minAge && person.Region == region;     } } ... Person person = list.Find(new PersonFinder(minAge,region).IsMatch); 

This is fairly comparable to how the compiler does it under the bonnet (actually, it uses public read/write fields, not private readonly).

The biggest caveat with C# captures is to watch the scope; for example:

        for(int i = 0 ; i < 10 ; i++) {             ThreadPool.QueueUserWorkItem(delegate             {                 Console.WriteLine(i);             });         } 

This might not print what you expect, since the variable i is used for each. You could see any combination of repeats - even 10 10's. You need to carefully scope captured variables in C#:

        for(int i = 0 ; i < 10 ; i++) {             int j = i;             ThreadPool.QueueUserWorkItem(delegate             {                 Console.WriteLine(j);             });         } 

Here each j gets captured separately (i.e. a different compiler-generated class instance).

Jon Skeet has a good blog entry covering C# and java closures here; or for more detail, see his book C# in Depth, which has an entire chapter on them.

like image 124
Marc Gravell Avatar answered Oct 06 '22 00:10

Marc Gravell


I agree with a previous answer of "all the time". When you program in a functional language or any language where lambdas and closures are common, you use them without even noticing. It's like asking "what is the scenario for a function?" or "what is the scenario for a loop?" This isn't to make the original question sound dumb, rather it's to point out that there are constructs in languages that you don't define in terms of specific scenarios. You just use them all the time, for everything, it's second nature.

This is somehow reminiscent of:

The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."

Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.

On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.

(http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html)

like image 30
Brian Avatar answered Oct 06 '22 00:10

Brian