Functions Tutorial

Functions are conventionally defined in Lua with the function keyword as follows:

function function_name ( args ) body end

The following example shows a simple function called "foo" that receives a single argument and returns twice its value:

Functions are values

The above syntax is actually just a convenience for the following equivalent syntax:

function_name = function( args ) body end

Thus, the above function can just as equally be written:

This alternate syntax shows most clearly the real nature of functions in Lua. function(n) return n*2 end itself is an expression that evaluates at runtime to a value (here, a function). This alone creates a function. The left-hand side of the statement then assigns the function to the variable foo. However, before the function is assigned to foo, the function has no name. It is an anonymous though still usable function, but when it is assigned to the variable foo, the function gains the name foo and can be called using that name.

As such, it is not necessary to name a function to use it. The following example creates a function anonymously and immediately calls it in an expression:

The important point of all this is that functions in Lua are values just like string and numbers are values. As values, they can be created during runtime, stored in variables, and passed to and returned from other functions. Since functions in Lua have all the rights and privileges to do all the fun things that other values do, they are said to be first class values.

Function values are references

When functions in Lua are passed around as values, they are treated as reference values just like tables. The reference refers to an object with a unique identity and lifetime containing the function body (code implementation). Therefore, when a function variable is assigned to another, the function code itself is not copied, but rather the reference is copied.

Functions are dynamically typed

Functions, like other values in Lua, are also dynamically typed. This means that we only find out if a value is a function when we check at runtime:

Note that we could not call the object x above because it is a string, but when we assign the function foo to the variable x, we can call it:

Functions, i.e. variables, in Lua can be dynamically changed at runtime. Dynamically changing the variable type at runtime is a powerful feature not found in statically typed languages such as C.

Notice that the type of a function is always simply "function" without further qualification, regardless of the number and types of the function's parameters and return values:

This differs from C in which the type of a function (its prototype) contains argument and return type information that must be explicitly specified before use. In Lua you do not need to declare types for values returned by functions or for arguments passed to functions! This allows Lua to deal with function arguments and return values in a flexible manner. Lua handles multiple arguments, variable argument lists, and multiple return values.

In particular, we have no problem assigning functions with different argument lists or return values to the variable x since x has no notion of the object assigned to it:

One must be careful not to name variables the same. A statically typed language, such as C, gives you compile errors when two or more functions are named the same, but this is not the case with a dynamic language such as Lua. Lua also allows us to easily write very flexible code.

Function destruction

Since functions are objects, they consume resources (system memory). Eventually they are destroyed. Like other objects, Lua destroys functions after they are no longer reachable:

Since foo is just a reference to a function body, we can assign other variables to have the same value. We can also delete the reference to foo by assigning the value nil to it. This effectively deletes the foo variable. Once we delete the reference from both foo and bar, the function is unreachable, and Lua will delete it -- i.e. Lua's Garbage Collector collects the unused function.

Next Tutorial