Functions Tutorial

lua-users home
wiki

Functions are covered in section 2.5.8 [1] of the Reference Manual.

Defining functions

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:

> function foo(n) return n*2 end
> = foo(7)
14

Functions are values

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

function_name = function( args ) body end

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

> foo = function(n) return n*2 end
> = foo(4)
8

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 function, though it is still a 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:

> = 1 + (function(n) return n*2 end)(4)
9

It can be handy to pass a function (even an anonymous one) directly to another function, such as the pairs function that passes each key-value pair in the given table to the given function:

> for i,v in pairs({'a',2,foo}) do
>     print(i,v)
> end
1       a
2       2
3       function: 0x687f10

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. Because functions in Lua have all the rights and privileges to do all the fun things that other values do, not to be treated as second-class citizens (as in C), they are said to be first class values.[2][3]

Function values are references

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

> foo = function(n) return n*2 end  -- create function and assign to foo
> bar = foo        -- bar and foo now refer to the same function
> = foo, bar
function: 0x687d20      function: 0x687d20
> = (foo == bar)
true
> =(function(n) return n*2 end)
function: 0x6870c0
> = (foo == (function(n) return n*2 end))  -- not the same function
false

Functions are dynamically typed

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

> x = "onion"
> = type(x)     -- What type are you, sir?
string
> x()           -- I will try to call you now.
stdin:1: attempt to call global `x' (a string value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
> x = foo
> = type(x)     -- What type are you, sir?
function
> = x(77)       -- I will try to call you now.
154

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. This is in contrast to statically typed languages (like C) that need to be told at compile time whether the variable x is a function, and that status cannot change at run-time.

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

> = type(foo)  -- What type are you, sir?
function

This differs from C, where 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. This is covered in more detail in the FunctionCallTutorial.

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

> x = function(a,b) return a+b, a-b end
> = x(5,6)
11      -1
> function x(a,b,c) return a..b..c end
> = x('a','b','c')
abc
Of course we must be careful that we don't accidentally name variables the same as we won't get the same errors reported on compilation, or at runtime as we would with a statically typed language. However, this functionality is very useful and allows us to write very flexible code simply.

Function destruction

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

> = foo
function: 0x688af8
> bar = foo  -- make bar reference the same function as foo
> foo = nil  -- foo no longer references the function...
> = bar      --   but bar still does.
function: 0x688af8
> bar = nil  -- bar no longer references the function either.
= bar, foo   -- no one references the function now (it is unreachable)
nil     nil
> foo()        -- try to invoke the function
stdin:1: attempt to call global `foo' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?

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 (see GarbageCollectionTutorial). In this instance we assigned the function body to the variable bar, so in a way we renamed the function. But when we set the variable bar to nil, there are no other variables pointing to the function body, and it will be deleted when the garbage collector is called.


FindPage · RecentChanges · preferences
edit · history
Last edited November 6, 2011 9:25 am GMT (diff)