How to Understand Closure in a Lambda

How to understand closure in a lambda?

Resolution of variables in lambdas is done when lambda is executed. At this time, for all buttons i=5. To rectify this issue do as follows:

 make_button = Tkinter.Button(frame, text ="make!", 
command= lambda i=i: makeId(i))

This creates i as a local variable in a lambda. This local variable will hold correct value of i from the loop. the local variable can have any name, not necessarily i, e.g. command= lambda a=i: makeId(a)).

What is the difference between a 'closure' and a 'lambda'?

A lambda is just an anonymous function - a function defined with no name. In some languages, such as Scheme, they are equivalent to named functions. In fact, the function definition is re-written as binding a lambda to a variable internally. In other languages, like Python, there are some (rather needless) distinctions between them, but they behave the same way otherwise.

A closure is any function which closes over the environment in which it was defined. This means that it can access variables not in its parameter list. Examples:

def func(): return h
def anotherfunc(h):
return func()

This will cause an error, because func does not close over the environment in anotherfunc - h is undefined. func only closes over the global environment. This will work:

def anotherfunc(h):
def func(): return h
return func()

Because here, func is defined in anotherfunc, and in python 2.3 and greater (or some number like this) when they almost got closures correct (mutation still doesn't work), this means that it closes over anotherfunc's environment and can access variables inside of it. In Python 3.1+, mutation works too when using the nonlocal keyword.

Another important point - func will continue to close over anotherfunc's environment even when it's no longer being evaluated in anotherfunc. This code will also work:

def anotherfunc(h):
def func(): return h
return func

print anotherfunc(10)()

This will print 10.

This, as you notice, has nothing to do with lambdas - they are two different (although related) concepts.

Example that requires a closure or lambda

Lambda calculus is actually pretty simple, and not that useful on its own. However it is when you start learning the implications of lambda calculus and strategies of application control using functional design patterns that you will become a better and more powerful programmer.

The premise is that functions are also values and this makes it really powerful for abstracting many concepts. Your two examples show the simplest way that closures and currying are implemented. Those are trivial examples. When you begin to program using a functional style, those pattern will come up over and over again as very powerful ways to abstract away complexity.

seperation of concerns

Functional programming is useful is when you start abstracting using higher order functions, the typical example being - I want to do something to a collection of objects.

so in an imperative program, you use a for loop:

result = Array(length);
for(i = 0; i < length; i++)
{
result[i] = dosomething(input[i]);
}

notice that in the block of code, the dosomething function is right in the middle of the for loop. You can't really separate out what you are doing to each element of the array from the actual for-loop control structure.

However, by using a functional style, the control structure of the loop is abstracted away using map - a higher order function - you get clear separation of two concepts of looping and function application. This is the equivalent code in scheme.

(define result (map dosomething collection))

map takes care of the fact that you are traversing each element of the array. dosomething takes care of the fact that you are performing an operation on each element of the array. Reasoning about this becomes much more clear and changing the code becomes much easier. Now imagine that every for loop in your code was replaced by this construct and how many lines of code it will save.

cheap constructors

Addressing the concept of closures and currying. There is an equivalence between objects and functions. Essentially, functions can be made to look and behave like objects. Javascript makes great use of this fact. Anything you can do with objects, you can also do with functions. In fact, by getting rid of the distinction between what an object is and what a function is, you have effectively decluttered your mind and have one way of thinking about the problem - that is, through code that is built up through functionality.

I am using clojure code here because it is what i'm comfortable with:

This is the clojure code for trivial adder example, With the adder example, you are calling a addn with the number 5 to get back function that adds 5 to a number. a general use case may be:

(defn addn [n] (fn [m] (+ m n))
(def add5 (addn 5))

(map add5 [1 2 3 4 5 6])
;; => [6 7 8 9 10 11]

Say you had a function download-and-save-to that takes a url and a database, saves the url to a database table and returns true when it is successful, you can do exactly the same abstraction as you did with +:

(defn download-url-to [db]
(fn [url] (download-and-save-to url db)))

(def download-url-mydb (download-url-to mydb))
(map download-url-mydb [url1 url2 url3 url4 url5])
;; => [true true false true true]

Notice that the structure is equivalent even though you are doing vastly different things. Think about how you would have approach this problem using java or c++. There would be a lot more code involved in class definitions, factory methods, class abstractions, inheritence.... essentially. you have to go through a whole lot more ceremony to get the same effect.

opening your mind

Because of the way you can express ideas so succinctly, functional programming can let you grasp many concepts that are very difficult to express in more verbose languages. The tool you pick will make exploring certain problems easier or harder.

I highly recommend clojure - (http://www.4clojure.com/) and lighttable - (http://www.lighttable.com/, http://www.kickstarter.com/projects/ibdknox/light-table) to get started. From my personal experience, my one year of learning and exploring concepts by the clojure community was akin to about 10 years of learning java, c++ and python combined.


Oh, did I mention how much fun I'm having learning all this stuff? Monads, combinators, propagators, continuations... all those scary looking academic concepts are actually well within reach when you have the right tools for understanding them.

What do lambda function closures capture?

What do the closures capture exactly?

Closures in Python use lexical scoping: they remember the name and scope of the closed-over variable where it is created. However, they are still late binding: the name is looked up when the code in the closure is used, not when the closure is created. Since all the functions in your example are created in the same scope and use the same variable name, they always refer to the same variable.

There are at least two ways to get early binding instead:

  1. The most concise, but not strictly equivalent way is the one recommended by Adrien Plisson. Create a lambda with an extra argument, and set the extra argument's default value to the object you want preserved.

  2. More verbosely but also more robustly, we can create a new scope for each created lambda:

    >>> adders = [0,1,2,3]
    >>> for i in [0,1,2,3]:
    ... adders[i] = (lambda b: lambda a: b + a)(i)
    ...
    >>> adders[1](3)
    4
    >>> adders[2](3)
    5

    The scope here is created using a new function (another lambda, for brevity), which binds its argument, and passing the value you want to bind as the argument. In real code, though, you most likely will have an ordinary function instead of the lambda to create the new scope:

    def createAdder(x):
    return lambda y: y + x
    adders = [createAdder(i) for i in range(4)]

Python lambda closure scoping

The reason is that closures (lambdas or otherwise) close over names, not values. When you define lambda x: test_fun(n, x), the n is not evaluated, because it is inside the function. It is evaluated when the function is called, at which time the value that is there is the last value from the loop.

You say at the beginning that you want to "use closures to eliminate a variable from a function signature", but it doesn't really work that way. (See below, though, for a way that may satisfy you, depending on what you mean by "eliminate".) Variables inside the function body will not be evaluated when the function is defined. In order to get the function to take a "snapshot" of the variable as it exists at function-definition time, you must pass the variable as an argument. The usual way to do this is to give the function an argument whose default value is the variable from the outer scope. Look at the difference between these two examples:

>>> stuff = [lambda x: n+x for n in [1, 2, 3]]
>>> for f in stuff:
... print f(1)
4
4
4
>>> stuff = [lambda x, n=n: n+x for n in [1, 2, 3]]
>>> for f in stuff:
... print f(1)
2
3
4

In the second example, passing n as an argument to the function "locks in" the current value of n to that function. You have to do something like this if you want to lock in the value in this way. (If it didn't work this way, things like global variables wouldn't work at all; it's essential that free variables be looked up at the time of use.)

Note that nothing about this behavior is specific to lambdas. The same scoping rules are in effect if you use def to define a function that references variables from the enclosing scope.

If you really want to, you can avoid adding the extra argument to your returned function, but to do so you must wrap that function in yet another function, like so:

>>> def makeFunc(n):
... return lambda x: x+n
>>> stuff = [makeFunc(n) for n in [1, 2, 3]]
>>> for f in stuff:
... print f(1)
2
3
4

Here, the inner lambda still looks up the value of n when it is called. But the n it refers to is no longer a global variable but a local variable inside the enclosing function makeFunc. A new value of this local variable is created every time makeFunc is called, and the returned lambda creates a closure that "saves" the local variable value that was in effect for that invocation of makeFunc. Thus each function created in the loop has its own "private" variable called x. (For this simple case, this can also be done using a lambda for the outer function --- stuff = [(lambda n: lambda x: x+n)(n) for n in [1, 2, 3]] --- but this is less readable.)

Notice that you still have to pass your n as an argument, it's just that, by doing it this way, you don't pass it as an argument to the same function that winds up going into the stuff list; instead you pass it as an argument to a helper function that creates the function you want to put into stuff. The advantage of using this two-function approach is that the returned function is "clean" and doesn't have the extra argument; this could be useful if you were wrapping functions that accepted a lot of arguments, in which case it could become confusing to remember where the n argument was in the list. The disadvantage is that, doing it this way, the process of making the functions is more complicated, since you need another enclosing function.

The upshot is that there is a tradeoff: you can make the function-creation process simpler (i.e., no need for two nested functions), but then you must make the resulting function a bit more complicated (i.e., it has this extra n=n argument). Or you can make the function simpler (i.e., it has no n=n argument), but then you must make the function-creation process more complicated (i.e., you need two nested functions to implement the mechanism).

Difference between a lambda function and a closure (in PHP)?

A closure is a lambda function in php that encapsulates variables so they can be used once their original references are out of scope.

A closure is a lambda function, but a lambda function is not a closure unless you specify the use keyword.

This is a much better answer: https://stackoverflow.com/a/220728/1152375

Understanding how closure works in python

First,

p = cons("a","b")

because in cons, it returns pair, it is functionally equivalent to

def p(f):
return f("a", "b")

then,

print(car(p))

Which evolve into

print(p(lambda a,b: a))

and that becomes

print((lambda a,b: a)("a", "b"))

and becomes

print("a")

C++ lambda lexical closure over local variables

    return [&count] () -> int {

This is a capture by reference. The lambda captures a reference to this object.

The object in question, count, is in the function's local scope, so when the function returns, count gets destroyed, and this becomes a reference to an object that went out of scope and gets destroyed. Using this reference becomes undefined behavior.

Capturing by value seems to solve this problem:

    return [count] () -> int {

But your obvious intent is so that each invocation of this lambda returns a monotonically-increasing counter value. And merely capturing the object by value is not enough. You also need to use a mutable lambda:

 return [count] () mutable -> int
{
return ++count;
};

But the pedantical answer to your question "what happens" is that a lambda is essentially an anonymous class, and what a lambda captures are really class members. Your lambda is equivalent to:

class SomeAnonymousClassName {

int &count;

public:
SomeAnonymousClassName(int &count) : count(count)
{}

int operator()
{
// Whatever you stick in your lambda goes here.
}
};

Capturing something by reference translates to a class member that's a reference. Capturing something by value translates to a class member that's not a reference, and the act of capturing lambda variables translates to passing them to the lambda class's constructor, which is what happens when you create a lambda. A lambda is really an instance of an anonymous class, with a defined operator().

In a regular lambda, the operator() is actually a const operator method. In a mutable lambda, the operator() is a non-const, a mutable operator method.



Related Topics



Leave a reply



Submit