Understanding Lambda/Closure, Part 1 - Learning from JavaScript



According to the Lambda page of Wikipedia:

In programming languages such as Lisp, Python and Ruby lambda is an operator used to denote anonymous functions or closures.

JDK8 will support the lambda syntax. But, what's lambda? How to use it? Java has been lacking lambda/closure, so it's an unfamiliar thing to many Java programmers. In fact, lambda/closure has existed in many programming languages. Java developers unfamiliar with lambda/closure can learn from other languages featured with lambda/closure and understand its concept and usage.

Take JavaScript, familiar to most developers, for example. We can define a function as follow:

function doSome(param) {
    // do something
}

In JavaScript, a function is actually an object. You can create a function object and assign it to a doSome variable as follow:

var doSome = function(param){
    // do Something
};

The bold part is a function literal in JavaScript. It'll create a Function instance. The created function object is not necessary assigned to a variable. In this condition, we usually say it's an anonymous function.

function(param) {
    // do something
};

If we ignore several details, the Function instance created by the above function literal is the same as new Function('param', '// do something'). It points out that a function itself is an object; that is, a value. If a function is an object, what it can do? It can be assigned to a variable:

function foo(param) {
    document.write(param, '<br>');
}
var zzz = foo;
zzz('demo');

The above code is the same as (or precisely speaking, similar to) the following:

var foo = function(param) {
    document.write(param, '<br>');
};
var zzz = foo;
zzz('demo');

Now that it can be assigned to other variables, it can be used as an argument passed to functions:

function show(element) {
    document.write(element, '<br>');
}
[1, 2, 3, 4, 5].forEach(show);

The above code is the same as (or precisely speaking, similar to) the following:

var show = function(element) {
    document.write(element, '<br>');
};
[1, 2, 3, 4, 5].forEach(show);

Understanding the concept of a programming language can be done not only from the syntax but also from its culture and coding styles. For example, using Java conventions to iterate a JavaScript array may write code with the following style:

var array = [1, 2, 3, 4, 5];
for(var i = 0; i < array.length; i++) {
    document.write(array[i] + '<br>');
}

Using JavaScript conventions or styles may iterate an array as follow:

[1, 2, 3, 4, 5].forEach(function(element) {
    document.write(element + '<br>');
});

Using syntax from the culture, conventions, and styles of a language makes you clearly understand the playground of syntax, such as lambda/closure.

Since a function can be used as an argument passed to functions, it can be a callback function is its enclosing function. For example, if your browser or JavaScript client doesn't support the forEach function for an array, you can design one by yourself.

Array.prototype.forEach = function(callback) {
    for(var i = 0; i < this.length; i++) {
        callback(this[i]);
    }
};

[1, 2, 3, 4, 5].forEach(function(element) {
    document.write(element + '<br>');
});

From all the above, we know if a function is an object, we can...
  • Assign it to a variable if necessary.
  • A function can be not only called passively but also passed to other functions to do something actively.
  • Different strategies in a code template can be replaced by callback functions.
That is, when a function is an object, it can be not only used to simplify syntax, but also trigger out different designs. Open various possibilities about programming.

From the above, we understand the concept about anonymous functions and function objects. As for why it is named "lambda", we'll explain in later articles. The next article will start from what a closure is.