Tutorial: Anonymous Functions and Closures

Share on Facebook0Share on Google+2Tweet about this on TwitterShare on LinkedIn1

This tutorial discusses the basics behind anonymous functions and closures in Lua. Let’s begin by inspecting how a typical Lua function looks:

Under the hood, this creates a variable called myFunction that is scoped locally to this code block and is stored where the code block exists in memory. For instance if you did…

…the Terminal/console would print something like this:


This is the location in memory where Lua will jump when the function is called.

Lua also permits you to define a function like this:

In this notation, it’s more clear that you’re assigning a variable to a code block (or more specifically the memory address of that code block). In the end, both notations accomplish the same thing, but the second notation allows some additional flexibility. When written in this form, you are effectively taking an unnamed block of code and giving it a name.

Lua permits you to write these functions and use them without a name.  This is called an anonymous function.

Anonymous Functions

To explore anonymous functions, let’s look at some examples :

In this case, the timer.performWithDelay() function takes a time interval in milliseconds, a function to execute, and an integer count to repeat. Thus, myFunction() will fire 10 times on every 1000 millisecond interval, but what’s really happening is that Lua is passing the memory address of the function to the timer.performWithDelay() function. This means that you could also write…

…or this (note the semicolon after the print() command…

In both cases, instead of using a variable to hold the function’s memory address, you simply create an unnamed anonymous function that will execute when the timer fires. Anonymous functions can be used anywhere you need to code an onComplete or callback listener function, for example in transition.to(), audio.play(), etc., but how often should you use them? From the perspective of code readability and sustainability, perhaps not very often — they tend to make your code harder to read, but if the function will only be used in that specific scope of your code, and it’s relatively short, anonymous functions are a valid coding technique.

In the second example, notice the semicolon at the end of line 3. If you write just one statement of code, for example one print() statement, the semicolon isn’t required, but if you write multiple statements on one line, they must be separated by semicolons. Therefore, it’s a good habit to include the semicolon, even if you just include one line of code within the anonymous function.

Be cautious: there are times when you can not use anonymous functions. One specific instance is when you assign functions to event listeners. Because the event listener system in Corona is based around storing the address of functions that are specified to handle events, the address that you pass in when removing an event listener via object:removeEventListener() must match the address that was passed in to object:addEventListener().

Lua Closures

Lua closures are another useful technique. Where they truly shine is in passing parameters to function handlers that are not looking for extra parameters. To illustrate this, let’s look at a transition.to() example:

In this example,  myFunction() will be passed a single parameter, target, which is the object that is transitioning. But let’s assume that the display object is a member of on array and you need to know more about the object itself in the function that gets called. This can be accomplished via a Lua closure:

In this example, instead of calling myFunction() as part of the callback, you call an anonymous function instead. That anonymous function takes the received target parameter that transition.to() provides and, inside it, you call your named function, passing along the target object reference and the color property of the ball.

Closures are more than just anonymous functions. When you have a function inside of a function, the child function has access to all of its parent’s local objects, or upvalues. Normally, when a function ends, any locally-scoped variables go out of scope, so when you call the function again, you begin anew. Consider this example:

Each time that you call counter(), it will print the value of 10 because when the function’s scope ends, so do its local variables.

Now let’s modify the function to actually return a function that does the counting:

At this point, we have a new function in our counter1 variable, and when we run it multiple times…

…Lua realizes that the anonymous function may still get used and that it should hold on to the current value of i in its current scope. This is what a Lua closure does for you.

To expand on this concept, if you were to create another counter, the following results would occur:

Essentially, each version of the anonymous function holds its own i and keeps it scoped within itself. So, when you create a second counter, i resets to 0 for that instance.

In Summary

As you can see, anonymous functions and closures provide a powerful way to keep track of variable instances on a per-function basis. In the context of Corona SDK, this allows you to pass parameters to functions in which you normally don’t control the passed-in content.

To continue your exploration of these topics, please continue to the Lua documentation site.

Share on Facebook0Share on Google+2Tweet about this on TwitterShare on LinkedIn1
Rob Miracle

Rob Miracle creates mobile apps for his own enjoyment and the amusement of others. He serves the Corona Community in the forums, on the blog, and at local events.

This entry has 10 replies

  1. Lerg says:

    I approve this tutorial.

    *Seal of Lerg’s approval*

  2. Lerg says:

    Functions in Lua are so called first class citizens http://en.wikipedia.org/wiki/First-class_function
    That basically means functions are just like any other variables, you can toss them around as you want.

  3. RichieLoco says:

    This really helps thanks! Closures (and other more advanced concepts) are covered in the “Corona SDK Hotshot” book, however, whilst being intuitive the book doesn’t explain too well these concepts – this has certainly filled a gap in my knowledge.


  4. William Bell says:

    Regarding to memory usage , the function will be retained in memory only if I assigned this to a variable right ?

    print ( counter 1 ( ) ); — result: 1
    print ( counter 2 ( ) ); — result: 1
    print ( counter 3 ( ) ); — result: 1
    memory usage : three function instances retained

    If calling the function directly, then can I assume:
    print ( counter ( ) ); — result 1
    print ( counter ( ) ); — result 1
    print ( counter ( ) ); — result 1
    memory usage : zero function instance retained

    Thanks for the tutorial writeup !

    • Rob Miracle says:

      Well the code is unlikely to be freed up in any case. It’s code it stays there. But the reference to the upvalues would be retained with the multiple functions.


      • William Bell says:

        ahh I see , thanks very much Rob!

    • Nathan says:

      Technically, counter() returns a function which needs to be called, so you would need to use:
      print( counter()() );
      To print “1”.

  5. Luis Herranz says:

    Thanks for the tutorial, good work.

    I’ve always wondered if there’s an elegant way to do this Javascript technique in Lua:
    var counter = function() {
    var i = 0;
    return function() {
    i = i + 1;
    return i;
    In this JS code you are creating and executing the parent function at the same time, so the final counter function is the one inside (with the upvalue i in its scope).

    • Star Crunch says:

      It’s easy enough. You just need some parentheses to get the grammar right.


      local counter = (function()
      local i = 0
      return function()
      i = i + 1
      return i
      print(counter()) — 1
      print(counter()) — 2

      • Luis Herranz says:

        Superb, didn’t know you can add parentheses like that. Thanks Star!

Leave a reply

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">