Anonymous functions & lambda expression

An anonymous funciton (also function literal or lambda abstraction) is a function definition that is not bound to an identifier. In other world, an anonymous function is only a function without function name.

Anonymous functions are sometimes called lambda expressions.

  • Python
a = ['house', 'car', 'bike']
>>> a.sort()
>>> print a
['bike', 'car', 'house']
>>> a.sort(lambda x,y: cmp(len(x), len(y)))
>>> print a
['car', 'bike', 'house']
  • Go
package main

import (
    "fmt"
)

func main() {

    f := func(name string) {
        fmt.Printf("Hello, %s\n", name)
    }

    f("World")
}
  • ES6
alert((x => x*x)(10));

Closures

Wiki: In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a record storing a function together with an environment: a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or storage location to which the name was bound when the closure was created. A closure-unlike a plain function-allows the function to access those captured variables through the closure’s reference to them, even when the function is invoked outside their scope.

MDN: Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.

Keypoints

  • a function together with an environment
  • unlike a plain function
  • variables that are used locally, but defined in an enclosing scope which name was bound when the closure was created

Lexical scoping

function init() {
    var name = "Mozilla"; // name is a local variable created by init
    function displayName() { // displayName() is the inner function, a closure
        alert (name); // displayName() uses variable declared in the parent function    
    }
    displayName();    
}
init();

init() creates a local variable name and then a function called displayName(). displayName() is an inner function that is defined inside init() and is only available within the body of that function. displayName() has no local variables of its own, however it has access to the variables of outer functions and so can use the variable name declared in the parent function.

Closure

function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

This code still works may seem unintuitive. Normally, the local variables within a function only exits for the duration of that function’s execution. Once makeFunc() has finished executing, it is reasonable to expect that the name variable will no longer be accessible. Since the code still works as expected, this is obviously not the case.

The solution to this puzzle is that myFunc has become a closure. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created. In this case, myFunc is a closure that incorporates both the displayName function and the “Mozilla” string that existed when the closure was created.

A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to the object oriented programming, where objects allow us to associate some data (the object’s properties) with on or more methods.

Consequently, you can use a closure anywhere that you might normally use an object with only a single method.

Enulating private methods with closures

var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var counter1 = makeCounter();
var counter2 = makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */

Creating closures in loops: A common mistake

  • JavaScript
<!DOCTYPE html>
<html>
<head>
    <title>Closures</title>
    <meta charset="utf-8">
    <script type="text/javascript">
        window.onload = function() {
            var lists = document.getElementsByTagName("li");
            
            for(var i = 0; i < lists.length; i++) {
                // Three closures have been created, but each one shares the same single environment.
                // By the time the onclick callbacks are executed, the loop has run its course
                // and the i variable (shared by all the closures) has been left pointing to the last with a value 2.
                lists[i].onclick = function(){
                    alert(i); // not work as expected.
                };
            }
            
            // solution 1
            // for(var i = 0; i < lists.length; i++) {
            //     var f = function(j) {
            //         lists[j].onclick = function(){
            //             alert(j);
            //         };
            //     }(i);
            // }
            
            // solution 2
            // for(var i = 0; i < lists.length; i++) {
            //     var f = function() {
            //         var j = i;
            //         lists[j].onclick = function(){
            //             alert(j);
            //         };
            //     }();
            // }
        };
    </script>
</head>
<body>
<ul>
    <li>0</li>
    <li>1</li>
    <li>2</li>
</ul>
</body>
</html>
  • golang
func Serve(queue chan *Request) {
    for req := range queue {
        sem <- 1
        go func() {
            process(req) // Buggy; see explanation below.
            <-sem
        }()
    }
}

The bug is that in a Go for loop, the loop variable is reused for each iteration, so the req variable is shared across all goroutines.

Here’s one way to do that, passing the value of req as an argument to the closure in the goroutine:

func Serve(queue chan *Request) {
    for req := range queue {
        sem <- 1
        go func(req *Request) {
            process(req)
            <-sem
        }(req)
    }
}

Another solution is just to create a new variable with the same name, as the belows:

Serve(queue chan *Request) {
    for req := range queue {
        req := req // Create new instance of req for the goroutine.
        sem <- 1
        go func() {
            process(req)
            <-sem
        }()
    }
}

Performance considerations

It is unwise to unnecessarily create functions within other function if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.

Implementation and theory

Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function’s lexical environment (i.e., the set of available variables) at the time when the closure was created. The referencing environment binds the non-local names to the corresponding variables in the lexical environment at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself. When the closure is entered at a later time, possibly with a different lexical environment, the function is executed with its non-local variables referring to the ones captured by the closure, not the current environment.


References