CSC/ECE 517 Fall 2012/ch1 1w32 cm: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(100 intermediate revisions by the same user not shown)
Line 1: Line 1:
        '''CLOSURES FOR STATICALLY TYPED LANGUAGES '''
   
''' CLOSURES FOR STATICALLY TYPED LANGUAGES '''


== '''INTRODUCTION''' ==
== '''INTRODUCTION''' ==
      
      
A closure is a function or reference to a function together with a referencing environment—a table
A closure is a function or reference to a function which has a referencing environment — a table
storing a reference to each of the non-local variables (also called free variables) of that function.[http://en.wikisource.org/wiki/Page:Scheme_-_An_interpreter_for_extended_lambda_calculus.djvu/22 1] A
storing a reference to each of the non-local variables (also called free variables) of that function.
closure—unlike a plain function pointer—allows a function to access those non-local variables even
A closure allows a function to access the non-local variables even outside its lexical scope.  
when invoked outside of its immediate lexical scope.Closures can typically be treated like any other programming
Closures can typically be treated like any other programming language objects, e.g. they can be stored  
language objects, e.g. they can be stored in variables, passed to functions, and so on. [http://en.wikipedia.org/wiki/Closure_(computer_science) 2]
in variables, passed to functions, and so on.  


The best way to understand closures is to think about an example in Scheme.
A closure can be thought of as the marriage between a function and the environment in which it was declared within. Exactly what this marriage looks like at an implementation level differs depending on the language.
 
[[File:closure2_thumb.png]]
 
[http://aspiringcraftsman.com/tag/javascript/ ''Copyrighted Image by Derek Greer, JavaScript Closures Explained, February 2012'']
 
 
Here is a closure in Python:


<pre>
<pre>
(define f (lambda (x)
def outsideFunc(a):
  def enclosedFunc(b):
    # a is "closed" in the definition of enclosedFunc
    return a + b


(lambda (y)
return enclosedFunc


(+ x y))))
first = outsideFunc(4)
second = outsideFunc(2)
 
first (5) # returns 9
second (1) # returns 3
</pre>
</pre>


This is the simplest non-trivial example using closures. Here f is a function of one argument (x).
When you call it, you pass it a single number as an argument, which gets bound to x. The return
value from calling the function is another function which takes one argument (lambda (y) ...) This
new function always adds x to its input (whichever x was passed when the function was created).
[http://joemorrison.org/projects/four-concepts/ 3]


Closures are far from new to computer science. They're a standard feature in older languages such as
Implementation of closures in python is done by function calls. Here, the call to outside_func creates a binding for a that is referenced inside the function enclosedFunc. Each call to outsideFunc creates a new instance of this function, but each instance has a link to a different binding of x. The example shows the closure of a being used to eliminate either a global or a constant, depending on the nature of a.
Scheme, Smalltalk, and Lisp, and have more recently made their way into dynamic languages such as Ruby
This is the simplest non-trivial example using closures.
and Groovy. Closures are a natural fit for statically typed, functional Scala, and recently many have
argued that they have a place in the Java language, too. [http://www.javaworld.com/javaworld/jw-06-2008/jw-06-closures.html 4]


== '''IMPORTANCE OF CLOSURES''' ==
== '''IMPORTANCE OF CLOSURES''' ==


The uses of closures:
Some uses of closures:


1. They are very usable for making code more clear and readable. And as we all know clean readable short code is a code that is easier to debug and contains   fewer bugs.
1. They are very usable for making code more clear and readable. And as we all know clean readable short code is a code that is easier to debug and contains fewer bugs.


For example in Java,
For example in Java,
Line 45: Line 53:
</pre>
</pre>


Would be replaced (if Java had closures) with:
This would be replaced (if Java had closures) with:


<pre>
<pre>
Line 57: Line 65:


<pre>
<pre>
  Return a list of all books with at least THRESHOLD copies sold.
  Return a list of all students  with at least the threshold grade.
(define (best-selling-books threshold)
(define (grade threshold)
   (filter
   (filter
     (lambda (book)
     (lambda (student)
       (>= (book-sales book) threshold))
       (>= (student-grade student) threshold))
     book-list))>
     student-list))>
 
</pre>
</pre>


In this example, the lambda expression (lambda (book) (>= (book-sales book) threshold)) appears within the function best-selling-books. When the lambda expression is evaluated, Scheme creates a closure consisting of the code for the lambda expression and a reference to the threshold variable, which is a free variable inside the lambda expression.
In this example, the [http://en.wikipedia.org/wiki/Lambda_expression lambda expression] (lambda (student) (>= (student-grade student) threshold)) appears within the function grade. When the lambda expression is evaluated, a closure consisting of the code for the lambda expression and a reference to the threshold variable are created .The reference is a free variable inside the lambda expression.


The closure is then passed to the filter function, which calls it repeatedly to determine which books are to be added to the result list and which are to be discarded. Because the closure itself has a reference to threshold, it can use that variable each time filter calls it. The function filter itself might be defined in a completely separate file.
The closure is then passed to the filter function, which calls it repeatedly to determine which books are to be added to the result list and which are to be discarded. Because the closure itself has a reference to threshold, it can use that variable each time filter calls it. The function filter itself might be defined in a completely separate file.
Line 74: Line 81:
<pre>
<pre>
// Return a list of all books with at least 'threshold' copies sold.
// Return a list of all books with at least 'threshold' copies sold.
function bestSellingBooks(threshold) {
function bestStudents(threshold) {
   return bookList.filter(
   return studentList.filter(
       function (book) { return book.sales >= threshold; }
       function (student) { return student.grade >= threshold; }
     );
     );}
}
</pre>
 
The function keyword is used here instead of lambda, and an Array.filter method[10] instead of a global filter function.
 
3.
Using Closures For Privacy:
 
With closures,private members that are shielded from the outside world are available:
 
<pre>
(function(higherLevelFunc){
  function myPrivateDisplayFunction(name) {
      return name;
  }
  higherLevelFunc.display = higherLevelFunc(name) {
      console.log(myPrivateDisplayFunction(name));
  }
})(window);
</pre>
</pre>


The function keyword is used here instead of lambda, and an Array.filter method[10] instead of a global filter function, but otherwise the structure and the effect of the code are the same.
In this way private members can be protected from the outside world.
At the top level, the  function object is an [http://en.wikipedia.org/wiki/Anonymous_function anonymous function]:
3.  Code like the following, which is common in functional languages, can be parallelized,without needing to create a pool of worker threads and hand off the closure to them:
<pre>
<pre>
results = map(closure, inputs, [0..numElements-1]);
(function(higherLevelFunc){
})(window);
</pre>
 
This anonymous function can be called right away. It is passed to a global context (window in this case) so the public function can be “exported”, but inner details are hidden. Because the function myPrivateDisplayFunction is a nested function, it exists only within the scope of the closure; so it can be used anywhere inside this scope and not elsewhere JavaScript will hold a reference to the private function for use inside the multiply function, but myPrivateMultiplyFunction cannot be accessed outside of the closure. Consider:
 
<pre>
display("Cheng") // => Cheng
myPrivateDisplayFunction("Cheng") // => ReferenceError: myPrivateDisplayFunction is not defined
</pre>
</pre>
In these languages, closures take away the pain of declaring a new function somewhere for short pieces of code.


4.  Because closures delay evaluation i.e., they do not "do" anything until they are called so they can be used to define control structures. For example,all  Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures also. In languages that allow assignment, multiple functions can be produced that close over the same environment, enabling them to communicate privately by altering that environment.
The closure allows to define a function for private use, while still allowing control over what the rest of the world sees.


5. A closure can be used to associate a function with a set of "private" variables, which persist over several invocations of the function. The scope of the    variable encompasses only the closed-over function, so it cannot be accessed from other program code. In stateful languages, closures can thus be used to implement paradigms for state representation and information hiding, since the closure's upvalues (its closed-over variables) are of indefinite extent, so a value established in one invocation remains available in the next. Closures used in this way no longer have referential transparency, and are thus no longer pure functions; nevertheless, they are commonly used in "near-functional" languages such as Scheme.
4. Because closures delay evaluation i.e., they do not "do" anything until they are called so they can be used to define control structures. For example,all Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures also. In languages that allow assignment, multiple functions can be produced that close over the same environment, enabling them to communicate privately by altering that environment.


== '''CLOSURES IN DYNAMICALLY TYPED LANGUAGES''' ==
== '''CLOSURES IN DYNAMICALLY TYPED LANGUAGES''' ==


 
The following are examples of closure usage in some of the dynamically typed languages.
      The following are examples of closure usage in some of the dynamically typed languages.:
          
          
===Perl ===
===Perl ===
Line 102: Line 133:


The following is a make_adder() function, in which the returned anonymous function
The following is a make_adder() function, in which the returned anonymous function
contains a reference to a lexical variable outside the scope of that function itself. Such a reference
contains a reference to a lexical variable outside the scope of that function itself.  
requires that Perl return a proper closure, thus locking in for all time the value that the lexical had
when the function was created.


sub make_adder {
<pre>
sub multiplier {


my $addpiece = shift;
my $multiply = product;


return sub { shift + $addpiece };
return sub { product * $multiply };


}
}


$f1 = make_adder(20);
$func1 = multiplier(20);


$f2 = make_adder(555);
$func2 = multiplier(555);
</pre>


Now &$f1($n) is always 20 plus whatever $n you pass in, whereas &$f2($n) is always 555 plus
Now &$func1($n) is always 20 times whatever $n you pass in, whereas &$func2($n) is always 555 times
whatever $n you pass in. The $addpiece in the closure sticks around.  
whatever $n you pass in. The $multiply in the closure sticks around.
[http://theoryx5.uwinnipeg.ca/CPAN/perl/pod/perlfaq7/What's_a_closure.html 11]


=== Ruby ===
=== Ruby ===


In Ruby, closures are supported through procs and lambdas. These constructs are very similar, but there are some subtle differences (I might do a post about that soon). Let's create a closure and see how it fulfils the two properties described above.
In Ruby, closures are supported through [http://http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ procs and lambdas]. These constructs are very similar, but there are some subtle differences.  
<pre>


<pre>
class StudentGrade
class SomeClass
   def initialize(grade)
   def initialize(value1)
     @grade = grade
     @value1 = value1
   end
   end
   
   
   def value_printer(value2)
   def printGrade(name)
     lambda {puts "Value1: #{@value1}, Value2: #{value2}"}
     lambda {puts "The student #{@name}'s  grade is : #{@grade} "}
   end
   end
end
end
   
   
def caller(some_closure)
def caller(closureVariable)
   some_closure.call
   closureVariable.call
end
end
   
   
some_class = SomeClass.new(5)
obj1 = StudentGrade.new('A')
printer = some_class.value_printer("some value")
closureCall = obj1.printGrade("Matt")
   
   
caller(printer)
caller(closureCall)
</pre>
</pre>


When we execute we get the following output:
Upon execution,get the following output:


<pre>
<pre>
alan@alan-ubuntu-vm:~/tmp$ ruby closures.rb
The student Matt's grade is A
</pre>


Value1: 5, Value2: some value
The printGrade function creates a closure, using the lambda construct, and then returns it. The closure is assigned to a variable, closureCall which is passed to another function caller, which then calls the closure. In this way a closure can be passed around.
</pre>


As you can see, the value_printer function creates a closure, using the lambda construct, and then returns it. We then assign our closure to a variable and pass that variable to another function, which then calls our closure. This satisfies the first property of a closure – we can pass it around. Notice also that when we called our closure, we printed out "5" and "some value". Even though both the @value1 and value2 variables were both well and truly out of scope in the rest of the program when we finally called the closure; inside the closure they were still in scope as it retained the state of all the variables that were in scope when it was defined. And so, our lambda satisfies the second property also which makes it a closure.
When we called the closure, both the variables name and grade were out of scope in the rest of the program. But when it is called ,they are still in scope as the closure retained the state of these variables
[http://www.skorks.com/2010/05/closures-a-simple-explanation-using-ruby/ 12]


== '''CLOSURES IN STATICALLY TYPED LANGUAGES''' ==
== '''CLOSURES IN STATICALLY TYPED LANGUAGES''' ==


While neither Java nor C++ support higher order functions directly, both provide mechanisms for
Closures increase considerably the level of a language by mixing access to local variables with
mimicking their behavior. Java's anonymous classes allow a function to be bundled with an object
remote execution of a set of locally-defined statements. However, to date closures have not been added
that can be treated much as a higher order function can. It can be bound to variables, passed
to statically-typed languages because it is difficult to type them and runtime errors occur if local
to other functions as an argument, and can be returned as the result of a function. However,
variables that no longer exist are accessed. Although these errors cannot be strictly considered “type
the function itself is named and thus cannot be treated in a generic fashion as true higher order
errors”, they make the language unsafe, which is against the philosophy of statically-typed languages.
functions can. C++ similarly provides partial support for higher order functions using function objects
(or "functors"), and add the further benefit that the function call operator may be overloaded so
that functors may be treated generically. Neither C++ nor Java, however, provides any support for
lexical closures.
 
 
=== '''C''' ===
 
The code below, written in C, implements the call unarySumFactory to produce unary sums. C does
not have syntactic support for closures. Nevertheless, we can implement closures by combining
high-order function calls with dynamic heap allocation.
[http://en.wikibooks.org/wiki/Introduction_to_Programming_Languages/Closures 13]


=== '''C++''' ===


C++ provides partial support for higher order functions using [http://en.wikipedia.org/wiki/Function_object function objects] (or "functors"), and has the additional benefit that the function call operator may be overloaded so that functors may be treated generically. A function object is the closest thing to a lexical closure in C++ .
Consider the following example:
<pre>
<pre>
#include <stdio.h>
struct Fobj{
#include <stdlib.h>
    Fobj(int var)
        : m_var(var){
    }


typedef struct struct_free_variables_unarySum {
    void operator()(string arg){
int x;
        std::cout << arg << m_var << std::endl;
} FREE_VARIABLES_unarySum;
    }


typedef struct {
    int m_param;
FREE_VARIABLES_unarySum* t;
int (*f)(FREE_VARIABLES_unarySum* t, int x);
} CLOSURE_unarySum;
 
int unarySum(FREE_VARIABLES_unarySum* t, int y) {
return y + t->x;
};
};


void* unarySumFactory(int x) {
Fobj f(10);
CLOSURE_unarySum* c = (CLOSURE_unarySum*) malloc (sizeof(CLOSURE_unarySum));
f("Implementing Function Objects in C++");
c->t = (FREE_VARIABLES_unarySum*) malloc (sizeof(FREE_VARIABLES_unarySum));
c->t->x = x;
c->f = &unarySum;
return c;
 
}
 
int test(int n) {
CLOSURE_unarySum* c = unarySumFactory(2);
int retVal = c->f(c->t, n);
free(c->t);
free(c);
return retVal;
}
 
int main(int argc, char** argv) {
printf("%d\n", test(argc));
return 0;
}
 
</pre>
</pre>
It doesn't capture local variables like a closure, local variable values have to be passed explicitly to the constructor instead because the stack frame is destroyed (and hence local variables) when the function returns.


=== '''Java''' ===
=== '''Java''' ===


The following is a code in Java programming  without closures
Although Java doesn't support higher order functions directly nor provide any support for lexical 
closures, it provides mechanisms for mimicking this behavior. Java's anonymous classes allow a function 
to be bundled with an object that can be treated just like a higher order function. It can be bound to 
variables, passed to other functions as an argument, and can be returned as the result of a function. However,
the function itself is named and therefore cannot be treated in a generic fashion, as true higher order
functions can.
Consider the following code without closures, written in Java:


<pre>
<pre>
Line 246: Line 249:
     }
     }
</pre>
</pre>
The example is admittedly contrived and extremely simple, but consider it: how often in Java do you find yourself implementing an interface and passing the implementation to a method for execution? We can think of three immediate examples:


Runnable and Callable, which we pass to threads or thread pools for asynchronous execution.
The above example is quite contrived and extremely simple, but then, there are few scenarios in Java, where an interface is implemented and the implementation is passed to a method for execution.
Callback interfaces such as ActionListener, which we register for future execution in case a certain event occurs.
Comparator, which we pass to a TreeMap for maintaining its sorting order.


In all these cases we use an interface, providing some functionality as an implementation of the interface. We then pass the functionality to a method for immediate or delayed, synchronous or asynchronous execution. Closures would simplify this process by allowing a more concise syntax, thereby eliminating some of Java's verbosity. Beyond allowing more concise and readable Java source code, closures would add some functionality completely new to Java, such as custom control structures.
* Runnable and Callable, which we pass to threads or thread pools for asynchronous execution.
* Callback interfaces such as ActionListener, which we register for future execution in case a certain event occurs.
* Comparator, which we pass to a TreeMap for maintaining its sorting order.


In all these cases an interface was used to provide some functionality as an implementation of the interface. The functionality is then passed to a method for immediate or delayed, synchronous or asynchronous execution. Closures would simplify this process by allowing a more concise syntax and increase the readability of the Java source code.Closures would also add some functionality completely new to Java, such as custom control structures.


== '''Challenges due to lack of closures in Statically typed languages''' ==


== '''Disadvantages of Lack of closures in Statically typed languages''' ==


 
Consider an example, given a list of students objects and a list of student leaders
Consider an example, given a list of employee objects and a list of those employees who are
is to be created, which can be determined with an IsLeader property.
managers is to be created, which can be determined with an IsManager property.


Using C#, it probably would be written like this
Using C#, it probably would be written like this


<pre>
<pre>
public static IList Managers(IList emps)
public static IList Leaders(IList studs)


{
{
Line 271: Line 273:
IList result = new ArrayList();
IList result = new ArrayList();


foreach(Employee e in emps)
foreach(Student s in studs)


if (e.IsManager) result.Add(e);
if (s.IsLeader) result.Add(s);


return result;
return result;
Line 281: Line 283:
In a language that has Closures, for example, Ruby, it would be written as,
In a language that has Closures, for example, Ruby, it would be written as,
<pre>
<pre>
def managers(emps)
def leaders(studs)


return emps.select {|e| e.isManager}
return studs.select {|s| s.isLeader}


end
end
Line 298: Line 300:
method,
method,
<pre>
<pre>
def highPaid(emps)
def highScorer (studs)


threshold = 150
high_score= 90


return emps.select {|e| e.salary > threshold}
return studs.select {|s| s.grade > high_score}


end
end
Line 308: Line 310:
Here the code in the select block is referring to a local variable defined in the enclosing method.
Here the code in the select block is referring to a local variable defined in the enclosing method.
Many of the alternatives to closures in languages that don't have real closures can't do that.  
Many of the alternatives to closures in languages that don't have real closures can't do that.  
[http://martinfowler.com/bliki/Closure.html 15]


Consider this function,
Consider this function,
<pre>
<pre>
def paidMore(amount)
def scoreMore(aggregate)


return Proc.new {|e| e.salary > amount}
return Proc.new {|s| s.grade >aggregate}


end
end
Line 321: Line 322:
sent into it.
sent into it.
<pre>
<pre>
highPaid = paidMore(150)
highScorer = scoreMore(90)
</pre>
</pre>
The variable highPaid contains a block of code (called a Proc in Ruby) that will return whether a
The variable highScorer contains a block of code (called a Proc in Ruby) that will return whether a
tested object has a salary greater than 150.
tested object has a grade greater than 90.
<pre>
<pre>
john = Employee.new
mary = Student.new


john.salary = 200
mary.grade = 110


print highPaid.call(john)
print highScorer.call(mary)
</pre>
</pre>


== REFERENCES ==
== CONCLUSION ==


# Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." (Wikisource)
In this article we have discussed closures, their importance and why it is challenging to implement them in statically typed languages. Examples in dynamically typed and statically typed languages have been illustrated. Statically typed languages like C, Java etc. use a different approach to implement the functionality of closures as illustrated in the examples.


# Wikipedia: Closure (computer science)
==ALSO READ==


# Joe Morrison: Brief introduction to four programming language concepts
#[http://en.wikipedia.org/wiki/Blocks_%28C_language_extension%29  "C language extension"]
#[http://en.wikipedia.org/wiki/Lexical_scope#Lexical_scoping "Lexical scoping"]
#[http://www.ibm.com/developerworks/java/library/j-jtp04247/index.html "Closures' debate in java"]


# Understanding the closures debate Does Java need closures? Three proposals compared By Klaus Kreft and Angelika Langer, JavaWorld.com, 06/17/08
== REFERENCES ==
 
#


#
#[http://en.wikisource.org/wiki/Page:Scheme_-_An_interpreter_for_extended_lambda_calculus.djvu/22 Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." (Wikisource)]
#[http://en.wikipedia.org/wiki/Closure_(computer_science) Wikipedia: Closure (computer science)]
#[http://ynniv.com/blog/2007/08/closures-in-python.html Closures in Python]
#[http://joemorrison.org/projects/four-concepts/ Joe Morrison: Brief introduction to four programming language concepts]
#[http://www.javaworld.com/javaworld/jw-06-2008/jw-06-closures.html Understanding the closures debate Does Java need closures? Three proposals compared By Klaus Kreft and Angelika Langer, JavaWorld.com] 
#[http://net.tutsplus.com/tutorials/javascript-ajax/closures-front-to-back/ Brian Scaturro: Closures: Front to Back]
#[http://stackoverflow.com/questions/1585717/why-are-closures-suddenly-useful-for-optimizing-programs-to-run-on-multiple-core stackoverflow: Why are closures suddenly useful for optimizing programs to run on multiple cores?]
#[http://theoryx5.uwinnipeg.ca/CPAN/perl/pod/perlfaq7/What's_a_closure.html perlfaq7 - General Perl Language Issues/ What's a closure?]
#[http://www.skorks.com/2010/05/closures-a-simple-explanation-using-ruby/ Alan Skorkin: Closures – A Simple Explanation (Using Ruby)]
#[http://stackoverflow.com/questions/1305570/closures-why-are-they-so-useful stackoverflow: Closures: why are they so useful?]
#[http://stackoverflow.com/questions/2009478/closures-in-c stackoverflow: Closures in C++]
#[http://en.wikibooks.org/wiki/Introduction_to_Programming_Languages/Closures Wikipedia: Introduction to Programming Languages/Closures]
#[http://www.jvoegele.com/software/langcomp.html Voegele.com/Programmer’s Corner/Programming Language Comparison]
#[http://martinfowler.com/bliki/Closure.html Martin Fowler’s Bliki - Closure]


#
== FURTHER READING ==


#
#[http://www.elonflegenheimer.com/2012/07/08/understanding-ruby-closures.html Understanding Ruby Closures by Elon Flegenheimer, July 2012]
#[http://www.shutupandship.com/2012/01/python-closures-explained.html Python Closures Explained by Praveen Gollakota, January 2012]
#[http://code.google.com/p/lambdaj/wiki/Closures Closures - How lambdaj 2.0 brings (almost) real closures to Java, October 2010]
#[http://dl.acm.org/citation.cfm?id=1026483 Closures for statically-typed object-oriented languages by José de Oliveira Guimarães, UFSCar, ACM SIGPLAN Notices Volume 39 Issue 8]
#[http://www.javac.info/closures-v05.html Closures for the Java Programming Language (v0.5)by Gilad Bracha, Neal Gafter, James Gosling, Peter von der Ahé]
#[http://www.codethinked.com/c-closures-explained C# Closures Explainedbby Justin Etheredge]

Latest revision as of 23:32, 19 September 2012

CLOSURES FOR STATICALLY TYPED LANGUAGES

INTRODUCTION

A closure is a function or reference to a function which has a referencing environment — a table storing a reference to each of the non-local variables (also called free variables) of that function. A closure allows a function to access the non-local variables even outside its lexical scope. Closures can typically be treated like any other programming language objects, e.g. they can be stored in variables, passed to functions, and so on.

A closure can be thought of as the marriage between a function and the environment in which it was declared within. Exactly what this marriage looks like at an implementation level differs depending on the language.

Copyrighted Image by Derek Greer, JavaScript Closures Explained, February 2012


Here is a closure in Python:

def outsideFunc(a):
  def enclosedFunc(b):
     # a is "closed" in the definition of enclosedFunc
     return a + b

 return enclosedFunc

first = outsideFunc(4)
second = outsideFunc(2)

first (5) # returns 9
second (1) # returns 3


Implementation of closures in python is done by function calls. Here, the call to outside_func creates a binding for a that is referenced inside the function enclosedFunc. Each call to outsideFunc creates a new instance of this function, but each instance has a link to a different binding of x. The example shows the closure of a being used to eliminate either a global or a constant, depending on the nature of a. This is the simplest non-trivial example using closures.

IMPORTANCE OF CLOSURES

Some uses of closures:

1. They are very usable for making code more clear and readable. And as we all know clean readable short code is a code that is easier to debug and contains fewer bugs.

For example in Java,

    button.addActionListener(new ActionListener() {
        @Override public void actionPerformed(ActionEvent e) {
            System.out.println("Pressed");
        }
    });

This would be replaced (if Java had closures) with:

button.addActionListener( { System.out.println("Pressed"); } );


2. Closures are used to implement continuation-passing style, and in this manner, hide state. Constructs such as objects and control structures can thus be implemented with closures. Closures typically appear in languages in which functions are first-class values—in other words, such languages allow functions to be passed as arguments, returned from function calls, bound to variable names, etc., just like simpler types such as strings and integers.

For example, consider the following Scheme function:

 Return a list of all students  with at least the threshold grade.
(define (grade threshold)
  (filter
    (lambda (student)
      (>= (student-grade student) threshold))
    student-list))>

In this example, the lambda expression (lambda (student) (>= (student-grade student) threshold)) appears within the function grade. When the lambda expression is evaluated, a closure consisting of the code for the lambda expression and a reference to the threshold variable are created .The reference is a free variable inside the lambda expression.

The closure is then passed to the filter function, which calls it repeatedly to determine which books are to be added to the result list and which are to be discarded. Because the closure itself has a reference to threshold, it can use that variable each time filter calls it. The function filter itself might be defined in a completely separate file.

Here is the same example rewritten in JavaScript, another popular language with support for closures:

// Return a list of all books with at least 'threshold' copies sold.
function bestStudents(threshold) {
  return studentList.filter(
      function (student) { return student.grade >= threshold; }
    );}

The function keyword is used here instead of lambda, and an Array.filter method[10] instead of a global filter function.

3. Using Closures For Privacy:

With closures,private members that are shielded from the outside world are available:

(function(higherLevelFunc){
   function myPrivateDisplayFunction(name) {
      return name;
   }
   higherLevelFunc.display = higherLevelFunc(name) {
      console.log(myPrivateDisplayFunction(name));
   }
 })(window);

In this way private members can be protected from the outside world.

At the top level, the function object is an anonymous function:

(function(higherLevelFunc){
})(window);

This anonymous function can be called right away. It is passed to a global context (window in this case) so the public function can be “exported”, but inner details are hidden. Because the function myPrivateDisplayFunction is a nested function, it exists only within the scope of the closure; so it can be used anywhere inside this scope and not elsewhere JavaScript will hold a reference to the private function for use inside the multiply function, but myPrivateMultiplyFunction cannot be accessed outside of the closure. Consider:

display("Cheng") // => Cheng
myPrivateDisplayFunction("Cheng") // => ReferenceError: myPrivateDisplayFunction is not defined

The closure allows to define a function for private use, while still allowing control over what the rest of the world sees.

4. Because closures delay evaluation i.e., they do not "do" anything until they are called so they can be used to define control structures. For example,all Smalltalk's standard control structures, including branches (if/then/else) and loops (while and for), are defined using objects whose methods accept closures. Users can easily define their own control structures also. In languages that allow assignment, multiple functions can be produced that close over the same environment, enabling them to communicate privately by altering that environment.

CLOSURES IN DYNAMICALLY TYPED LANGUAGES

The following are examples of closure usage in some of the dynamically typed languages.

Perl

The following is a make_adder() function, in which the returned anonymous function contains a reference to a lexical variable outside the scope of that function itself.

sub multiplier {

my $multiply = product;

return sub { product * $multiply };

}

$func1 = multiplier(20);

$func2 = multiplier(555);

Now &$func1($n) is always 20 times whatever $n you pass in, whereas &$func2($n) is always 555 times whatever $n you pass in. The $multiply in the closure sticks around.

Ruby

In Ruby, closures are supported through procs and lambdas. These constructs are very similar, but there are some subtle differences.


class StudentGrade
  def initialize(grade)
    @grade = grade
  end
 
  def printGrade(name)
    lambda {puts "The student #{@name}'s  grade is : #{@grade} "}
  end
end
 
def caller(closureVariable)
  closureVariable.call
end
 
obj1 = StudentGrade.new('A')
 closureCall = obj1.printGrade("Matt")
 
caller(closureCall)

Upon execution,get the following output:

The student Matt's grade is A

The printGrade function creates a closure, using the lambda construct, and then returns it. The closure is assigned to a variable, closureCall which is passed to another function caller, which then calls the closure. In this way a closure can be passed around.

When we called the closure, both the variables name and grade were out of scope in the rest of the program. But when it is called ,they are still in scope as the closure retained the state of these variables

CLOSURES IN STATICALLY TYPED LANGUAGES

Closures increase considerably the level of a language by mixing access to local variables with remote execution of a set of locally-defined statements. However, to date closures have not been added to statically-typed languages because it is difficult to type them and runtime errors occur if local variables that no longer exist are accessed. Although these errors cannot be strictly considered “type errors”, they make the language unsafe, which is against the philosophy of statically-typed languages.

C++

C++ provides partial support for higher order functions using function objects (or "functors"), and has the additional benefit that the function call operator may be overloaded so that functors may be treated generically. A function object is the closest thing to a lexical closure in C++ . Consider the following example:

struct Fobj{
    Fobj(int var)
        : m_var(var){
    }

    void operator()(string arg){
         std::cout << arg << m_var << std::endl;
    }

    int m_param;
};

Fobj f(10);
f("Implementing Function Objects in C++");

It doesn't capture local variables like a closure, local variable values have to be passed explicitly to the constructor instead because the stack frame is destroyed (and hence local variables) when the function returns.

Java

Although Java doesn't support higher order functions directly nor provide any support for lexical  closures, it provides mechanisms for mimicking this behavior. Java's anonymous classes allow a function  to be bundled with an object that can be treated just like a higher order function. It can be bound to  variables, passed to other functions as an argument, and can be returned as the result of a function. However, the function itself is named and therefore cannot be treated in a generic fashion, as true higher order functions can. Consider the following code without closures, written in Java:

public interface Block<T> {
     void invoke(T arg);
    }
    public class Utils {
     public static <T> void forEach(Iterable<T> seq, Block<T> fct) {
       for (T elm : seq)
       fct.invoke(elm);
     }
    }
    public class Test {
     public static void main(String[] args) {
       List<Integer> nums = Arrays.asList(1,2,3);
       Block<Integer> print = new Block<Integer>() {
         public void invoke(Integer arg) {
           System.out.println(arg);
         }
       };
       Utils.forEach(nums,print);
     }
    }

The above example is quite contrived and extremely simple, but then, there are few scenarios in Java, where an interface is implemented and the implementation is passed to a method for execution.

  • Runnable and Callable, which we pass to threads or thread pools for asynchronous execution.
  • Callback interfaces such as ActionListener, which we register for future execution in case a certain event occurs.
  • Comparator, which we pass to a TreeMap for maintaining its sorting order.

In all these cases an interface was used to provide some functionality as an implementation of the interface. The functionality is then passed to a method for immediate or delayed, synchronous or asynchronous execution. Closures would simplify this process by allowing a more concise syntax and increase the readability of the Java source code.Closures would also add some functionality completely new to Java, such as custom control structures.

Challenges due to lack of closures in Statically typed languages

Consider an example, given a list of students objects and a list of student leaders is to be created, which can be determined with an IsLeader property.

Using C#, it probably would be written like this

public static IList Leaders(IList studs)

{

IList result = new ArrayList();

foreach(Student s in studs)

if (s.IsLeader) result.Add(s);

return result;

}

In a language that has Closures, for example, Ruby, it would be written as,

def leaders(studs)

return studs.select {|s| s.isLeader}

end

Essentially select is a method defined on the Ruby collection class. It takes a block of code, a closure, as an argument. Select iterates through the input array, executes the block of code with each element, and returns an array of those elements for which the block evaluated as true.

The workaround in C could be using a function pointer; in Java with an anonymous inner class; and with a delegate in C#. These mechanisms are similar to closures, but there are two telling differences.

The first difference is closures can refer to variables visible at the time they were defined. Consider this method,

def highScorer (studs)

high_score= 90

return studs.select {|s| s.grade > high_score}

end

Here the code in the select block is referring to a local variable defined in the enclosing method. Many of the alternatives to closures in languages that don't have real closures can't do that.

Consider this function,

def scoreMore(aggregate)

return Proc.new {|s| s.grade >aggregate}

end

This function returns a closure, indeed it returns a closure whose behavior depends on the argument sent into it.

highScorer = scoreMore(90)

The variable highScorer contains a block of code (called a Proc in Ruby) that will return whether a tested object has a grade greater than 90.

mary = Student.new

mary.grade = 110

print highScorer.call(mary)

CONCLUSION

In this article we have discussed closures, their importance and why it is challenging to implement them in statically typed languages. Examples in dynamically typed and statically typed languages have been illustrated. Statically typed languages like C, Java etc. use a different approach to implement the functionality of closures as illustrated in the examples.

ALSO READ

  1. "C language extension"
  2. "Lexical scoping"
  3. "Closures' debate in java"

REFERENCES

  1. Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." (Wikisource)
  2. Wikipedia: Closure (computer science)
  3. Closures in Python
  4. Joe Morrison: Brief introduction to four programming language concepts
  5. Understanding the closures debate Does Java need closures? Three proposals compared By Klaus Kreft and Angelika Langer, JavaWorld.com
  6. Brian Scaturro: Closures: Front to Back
  7. stackoverflow: Why are closures suddenly useful for optimizing programs to run on multiple cores?
  8. perlfaq7 - General Perl Language Issues/ What's a closure?
  9. Alan Skorkin: Closures – A Simple Explanation (Using Ruby)
  10. stackoverflow: Closures: why are they so useful?
  11. stackoverflow: Closures in C++
  12. Wikipedia: Introduction to Programming Languages/Closures
  13. Voegele.com/Programmer’s Corner/Programming Language Comparison
  14. Martin Fowler’s Bliki - Closure

FURTHER READING

  1. Understanding Ruby Closures by Elon Flegenheimer, July 2012
  2. Python Closures Explained by Praveen Gollakota, January 2012
  3. Closures - How lambdaj 2.0 brings (almost) real closures to Java, October 2010
  4. Closures for statically-typed object-oriented languages by José de Oliveira Guimarães, UFSCar, ACM SIGPLAN Notices Volume 39 Issue 8
  5. Closures for the Java Programming Language (v0.5)by Gilad Bracha, Neal Gafter, James Gosling, Peter von der Ahé
  6. C# Closures Explainedbby Justin Etheredge