Liam,
I simply cannot accept that two basic elements of a
programming
language (or family thereof), which several here are maintaining is
the best one for beginners to learn, is more complex than this.
I think it is possible to have simple explanations. But it depends on
having a good idea of what the listner already knows. This isn't my case
with you, but as I did see that you didn't like Lisp nor Python examples
I will make up my own notation here and see if that helps.
A lambda expression just associates a list of names with some
computation using those names. Here is one that given two numbers will
return the sum of the squares of those numbers:
(x,y)==>(x*x+y*y)
This is supposed to be a big right arrow. Now lambda calculus is a whole
area of math which has lots to say about lambda expressions. For
example, it says that the actual names aren't important so that this new
lambda expression is entirely equivalent to the first one:
(a,b)==>(a*a+b*b)
I mentioned computation, but so far we haven't had any. We can apply a
lambda expression to a list of values and that will allow us to get a
result. I will use a colon to indicate that the expression on the left
is being applied to the values on the right:
(a,b)==>(a*a+b*b) : (3,4)
This is exactly the same thing as
(3*3+4*4)
which happens to be
(9+16)
which can be simply written as
25
So how is this different from a function call in C? Except for the fact
that I didn't give it some name like squaresum() or something like that
it seems like the same thing. There are lots of interesting details in
lambda calculus (specially the focus on recursive functions), but let's
ignore all that and move on the closures. What would happen if we try to
find the value of the following expression?
(a,b)==>(a*a+b*b+c*c) : (3,4)
The best we can do is get down to
(25+c*c)
We can say that variables "a" and "b" were bound to some values, but
"c"
remains unbound. It is a free variable in this expression. Here is a way
to fix that:
[ (c)==>( (a,b)==>(a*a+b*b+c*c) ) : (5) ] : (3,4)
I just used the square brackets to make things a little less confusing,
but they are the same thing as parenthesis. This complicated expression
is the same as
(a,b)==>(a*a+b*b+125) : (3,4)
Here "c" is no longer a free variable (also known as an unbound variable
or an open variable). It has been bound to a specific value. We can say
it has been closed.
If we have a way to refer to the thing in the square brackets and save
it and later manipulate it, we can do some interesting stuff. Given that
this thing has closed over a variable in a lambda expression that would
otherwise be free/open/unbound we can call it a closure.
You can think of a lambda expression as an anonymous function, and of a
closure as a lambda expression that is not loose in the world but exists
in a context (or environment) where its free variables have been
associated with values.
What is the big deal? You can store lambdas and closures in variables,
you can return them from functions and manipulate them in several ways.
In languages which don't present these concepts to the programmers they
are still there, but now hidden in the implementation and out of reach.
So these things are rather advanced and won't help at all children take
their first steps into programming. But they allow you to tell an
interesting story about how things work inside to an advanced learner
without having to drop down to the level of assembly language.
-- Jecel