I've spent an hour reading many posts on this site and others about lambdas and closures. I think I understand what they are, i.e. how they work, but I do not understand why they exist. Many examples I see refer vaguely to their "power," but in each of those cases I can think of a much simpler way to accomplish what is being illustrated. Maybe this is due to the examples being intentionally overly simple (for ease of understanding), or maybe I'm dense. But what I'd really like is to see a clear example of something you can accomplish with a closure or lambda that you can't accomplish without one. Maybe this is a loaded question, since all programming paradigms eventually boil down to the same machine instructions, and anything that can be done in one language can be done in another, somehow. So I guess what I'm really asking is for an example of something done with a closure that is more elegant than when done without (which does not seem to be the case for any example I've seen yet).
Here's what I'm talking about.
The leading answer for What is a 'Closure'? , an example in Scheme:
(define (make-counter)
(let ((count 0))
(lambda ()
(set! count (+ count 1))
count)))
(define x (make-counter))
(x) returns 1
(x) returns 2
...etc...
I don't know Scheme really, but I think I see what's going on. However, wouldn't this be more straightforward and accomplish the same thing? Pseudocode:
function incrementCount(var counter) {
counter++;
return counter;
}
counter = 1;
counter = incrementCount(counter);
counter = incrementCount(counter);
Here's another one on lambdas: What is a lambda (function)?
The JavaScript example given:
var adder = function (x) {
return function (y) {
return x + y;
};
};
add5 = adder(5);
add5(1) == 6
Again, why do it that way? Why not just say:
function adder(x, y) {
return x + y;
}
adder(5, 1);
Every example I've seen seems like an overly complicated way to do something that can easily be done with basic functions. These examples certainly don't illustrate any amazing cool "power" that I can see. So please, somebody enlighten me, I must be missing out on something. Thanks.
A lambda expression is an anonymous function and can be defined as a parameter. The Closures are like code fragments or code blocks that can be used without being a method or a class. It means that Closures can access variables not defined in its parameter list and also assign it to a variable.
The lambda operator cannot have any statements and it returns a function object that we can assign to any variable. For example: remainder = lambda num: num % 2 print(remainder(5)) Output 1. In this code the lambda num: num % 2 is the lambda function.
Lambda functions may be implemented as closures, but they are not closures themselves. This really depends on the context in which you use your application and the environment. When you are creating a lambda function that uses non-local variables, it must be implemented as a closure.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.
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.
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.
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.
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.
This question is rather difficult to answer because you’ve already covered all your bases: You’ve already seen examples, descriptions, explanations — and you even realise that lambda expressions compile down into a machine language which itself doesn’t have lambda expressions as a primary feature.
Nonetheless, I am going to try giving one example which seems to be among the most common use-cases in which I, personally, use a lambda expression. I use C#, which is fundamentally an imperative language, but has lambda expressions as a built-in feature, so my examples will be in C#.
Imagine you have a function that needs a value. But this value is expensive to compute, so the requirements are:
Lambda expressions make this very easy because you can use captured variables to “cache” the computed value:
bool computed = false;
MyType value = null;
var getValue = () => {
if (!computed)
{
value = computeValue(); // this is the expensive operation
computed = true;
}
return value;
};
Now I can pass getValue
into any function, and no matter what this function does with it (i.e. how many times it calls it), I know that computeValue()
will only be called once.
To do the same thing without a lambda, I would have to create a class equivalent to this lambda’s closure, and have it implement some sort of interface, for example:
sealed class Closure : IGetMyTypeValue
{
bool Computed = false;
MyType Value = null;
public Closure() { }
public MyType GetValue() // implements IGetMyTypeValue.GetValue()
{
if (!Computed)
{
Value = ComputeValue(); // this is the expensive operation
Computed = true;
}
return Value;
}
private MyType ComputeValue()
{
// expensive code goes here
}
}
[...]
var closure = new Closure();
// pass closure to a method that expects an IGetMyTypeValue
The downsides of having to write this large class are:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With