Closures
Closures are a bit hard to understand concept for someone from an Object
Oriented programming background, mainly because popular OO programming
languages, (Java/C++) does not have this feature (As
bjzaba
pointed out in
reddit, C++ 11 has Closures) haven’t embraced
or promoted this feature until recently. It is more of a functional programming
concept, although many Object Oriented languages has started to support Closures
through first class functions or higher order functions.
I first heard about Closures while developing something in Javascript. If you have used the popular javascript library jQuery, you have already used closures, knowingly or unknowingly.
Here is my attempt to explain Closures, through examples in few programming languages.
From Wikipedia:
In programming languages, a closure (also lexical closure or function closure) is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or up values) of that function. A closure—unlike a plain function pointer—allows a function to access those non-local variables even when invoked outside its immediate lexical scope.
What that means:
- Closure is a function (or a reference to a function)
- You get a pointer to closure
- So you can pass it around like an object
- It knows about non-local variables
- It can access those non-local variables, even when invoked outside of its scope
- So we say, closures ‘closes’ on its environment
- A function may create a closure and return it.
Few programming languages, that support Closures #
- Lisp
- Javascript
- Scala
- Clojure
- Ruby
- Python
- Haskell
- PHP
In closures procedure/method/function contexts become first-class. That means, with closures you can create functions that return functions, although that is only an outcome. An important point to understand here is, the closure methods refer to the context in which it was created, not to the one it was called.
To better understand closures one has to understand a variable’s scope, the best read about that would be understanding javascript varialble scope.
Closures store references to the outer function’s variables; they do not store the actual value. So if we change the value of reference in closure it changes value outside of its scope.
You may implement closures using Anonymous functions, but all anonymous functions need not be a closure, although many of them are.
Why would anyone use Closures? #
- Reusability
- Do more with less code
- Make functional code stateful
Closures help us to write more expressive and concise code(once you get a hang of it!). We know objects have a state, using Closure we can give state to functions as well. Now, let us take a look at examples of how to use closures in a few programming languages.
Examples #
All of the following examples do the same thing: Create a closure to increment a number by another number.
1. Closure example in Javascript #
This would be the easiest to understand code.
Closure example in Javascript
|
|
In the Javascript example above, we define a function incrementBy(x)
, which
returns a function, that accepts parameter ‘y’ and returns sum of x and y. Here
the value of ‘x’ will go into the closure of the returned function and will be
accessible whenever the function is invoked. Note that when calling
incrementBy2(4)
our closure remembers the value 2 (i.e ‘x’) that was passed
earlier when doing var incrementBy2 = incrementBy(2);
.
And when invoking incrementBy2(4)
we are actually passing the value of y
as 4. Hence the statement return x+y
will transform to return 2+4
. Cool
right!!?
2. Closure example in Scala #
Closure example in Scala
|
|
The example in Scala is similar to the example in Javascript except for Scala’s awesome one liner syntax.
3. Closure example in Lisp (Clisp) #
|
|
There are several ways of doing this is lisp. This is only one way of doing it. Here you are not getting a pointer to the closure function and will probably make it useless. See this link to see how to return functions is Clisp.
4. Closure example in Clojure #
|
|
As you can see, the syntax of clojure and lisp are extremely similar.
5. Closure example in Python #
|
|
The above example in Python is pretty similar to the one in Javascript and is
easy to understand. Here we define the closure function increment(y)
and then
return it. Just remember to take care of the tabs!
6. Closure example in Ruby #
|
|
Ruby can do this is in two ways, using Proc and using lambda. The lambda functions in Ruby are similar to lambda’s in lisp.
So that was examples about closures. Hope that gives you at least some idea about Closures. If you know how do the same in any other languages, please feel free to share. Also checkout the references, they are good reads.
References: #
- Martin Fowler on Lambda
- https://www.skorks.com/2010/05/closures-a-simple-explanation-using-ruby/
- https://stackoverflow.com/questions/111102/how-do-javascript-closures-work
- https://psg.com/~dlamkins/sl/chapter11.html#closures
- https://innig.net/software/ruby/closures-in-ruby
- https://en.wikipedia.org/wiki/Closure_(computer_programming)
- https://learn.jquery.com/javascript-101/closures/
- https://javascriptissexy.com/understand-javascript-closures-with-ease/
- https://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/
- https://csharpindepth.com/Articles/Chapter5/Closures.aspx
Thanks to Craig for sharing Go snippet
Reddit thread here: https://redd.it/223b7p