Lua: Functions

From Mario Fan Games Galaxy Wiki
Lua
Lua.gif
Basics
Intermediate
Advanced
XLua
Add to this template
 Standardwikimessagebox.png This article assumes the use of Lua 5.1.

Information may not be accurate or may need revision if you are using a different version.

Functions are self-contained chunks of code that can be called repeatedly. They may or may not take arguments, and may or may not return something. In Lua, functions are first-class, meaning they are treated like a normal variable as opposed to a special construct as in other languages such as C or C++. As a consequence, they can be stored in tables, passed around as arguments, and generally treated like regular data.

Functions in Lua may be anonymous, meaning they are not permanently bound to a specific name; to be more precise, all functions are anonymous, but are generally assigned to a variable. This is not required, however, and some library functions can take anonymous functions as a way of customizing their behavior, such as table.sort or string.gsub.

An example of defining and using functions:

function add(x, y)
    return x + y
end

print(add(5, 10)) --> 15

And because functions are anonymous, the following is exactly the same as the above:

add = function (x, y)
    return x + y
end

print(add(5, 10)) --> 15

There are a few subtle differences between the two in some cases (defining methods and how to define the function as local), but their behavior is exactly the same. Note that only the latter case is valid when used within a table constructor expression.

Methods

Methods are another type of function; they are effectively the same, but they operate on objects. Their first argument is the object to act upon, but this argument may be implicit through use of Lua's colon syntax, or explicit by using dot syntax as if the method were a normal function. If the object argument is implicit, Lua uses the variable name self within the method to reference the object.

A good example of methods is the string library:

-- reversing a string, dot syntax:
string.reverse("this is a test")

-- same, but using colon syntax:
("this is a test"):reverse()

The above is possible with strings as loading the string library changes the metatable of strings to the string table.

More information on methods and code examples can be found here

Closures

Closures are functions using upvalues: local variables within the same scope but outside the function itself. Closures can maintain the state of their upvalues between calls, which makes them useful as iterator functions. In fact, each closure has its own copy of these upvalues so multiple instances of a closure can exist at a time, without affecting each other. The following example shows two closures that keep track of how many times they have been called:

function new_call_counter ()
    local count = 0 -- upvalue
    return function () -- the actual closure
        count = count + 1
        return count
   end
end

x = new_call_counter()
y = new_call_counter()

x() x() x() x() x()

print(x()) --> 6
print(y()) --> 1