Closures in different languages

In most scripting languages, there are first-class functions. In short, first-class functions refer to functions that can serve as call arguments, work in expressions and be assigned to variables.

So what is a closure? A closure is a function that brings context information with it. Among all the languages, JavaScript is probably the language where closure is mostly frequently used. In my opinion, the reason why closures are so widely used in Javascript lies in that Javascript does not have a mature OO system compared to other programming languages.

function a()
{
    var t = 1;
    function b()
    {
        console.log(++t);
    }
    return b;
}

x = a();
x();
x();

The output of this piece of Javascript code is “2” and “3”. As we can see, function a() returned another function. However, this function not only carries the information about itself, but also the context it lies in, i.e. the value of variable t.

In Apple’s programming language Swift, we have similar closures that act almost identical to Javascript’s.

import Foundation

func a() -> (Void -> Void){
    var t = 1;
    func b() -> Void{
        println(++t);
    }
    return b;
}

var x = a();
x();
x();

The result is also the same as Javascript’s, “2” and “3”. What about Python?

def a():
   t = 1;
   def b(t = t):
      t += 1;
      print(t);
   return b;

x = a();
x();
x();

There are a few notable differences here. First of all, the variable t defined in a() is not visible to b(), thus it must be passed through named argument. Secondly, the output is “2” and “2”. This is reasonable since the value of t is passed through an argument and changing the value of the argument will not affect its original value. However, python do support “real” closures. The trick is to change the t into a nonlocal variable.

def a():
   t = 1;
   def b():
      nonlocal t;
      t += 1;
      print(t);
   return b;

x = a();
x();
x();

Now we are finally there. Next up, Groovy.

def a()
{
    int t = 1;
    return { -> println(++t)};
}

x = a();
x();
x();

Since in Groovy, named functions cannot be defined in another function, we can only use unnamed function to do this. The output is “2” and “3”.

In Java, functions are not first-class members, thus we will never have terms like closure. A workaround for this is to use anonymous class. Here is an example.

public class Closure
{
   public static Function a()
   {
      final int t = 1;
      return new Function(){
         @Override
         public void call()
         {
            System.out.println(t + 1);
         }
      };
   }

   public static void main(String[] args)
   {
      Function x = a();
      x.call();
      x.call();
   }
}

interface Function
{
   public void call();
}

Rule No.1 for anonymous class is that you cannot change the value of the variables that exist in the stack context. In other words, the variables on the stack are all “final” to the inner class. If one want’s to change the value of it, it must be declared as a field of a Class, which will be stored in heap.

Leave a Reply

Your email address will not be published. Required fields are marked *