A function is an encapsulation of code into a named chunk that can be reused and executed more than once. This is useful for seperating actions of a program that are written often into their own section to remove redundancy, boost code quality, and improve maintainability. Even if a section of code is only used once, if it is sufficiently complex or intricate (A good measure of this is often cyclomatic complexity), often it can be helpful to abstract those actions into their own function.
In Lua, functions are first class values, which means that functions are treated like any other value, like
"String" with regards to how one can store and create them. Specifically this means that one can assign a function to a variable, pass a function as an argument, or return a function from another function.
To define a function, state the keyword
function (optionally preceded by
local to lexically localize it as opposed to defining it globally) followed by a name, and then a set of parentheses optionally containing a list of arguments (essentially local variables) that will be given to the function's environment when called. To return one or more values from a function, use the keyword
return followed by a comma seperated list of the values/variables to return.
return will stop execution of the function, anything after a return is evaluated will not be run, and (if it is in the same block as the
return) is a syntax error.
Functions are called, which means to execute their contents, by stating their name followed by a set of parentheses, optionally containing any arguments (values) that you wish to pass along. When the function returns back to where it was called, it may return any amount of values, including
Note: Strictly speaking, the method of defining a named function as described above is syntactic sugar for the following statement:
local myFunc; myFunc = function(myArg, myOtherArg) --[[Do some code]] end -- Which is equivalent to: local function myFunc(myArg, myOtherArg) -- Do some code end
Which means that if you forward declare a variable for your function (that is to say, write
local myFuncName before the actual definition of the function) you should not use the
local keyword, as the variable it will be stored in is already localized. For example:
local myFunc -- Forward declaration -- Maybe do or setup some other stuff, myFunc is in scope here function myFunc(myArg, myOtherArg) -- Do some other code end
myFunc in the above snippet is lexically scoped to where the forward declaration was written because the declaration merely assigned a value to the previously defined variable
myFunc. This is semantically equivalent to the following snippet:
local myVar -- Maybe do something, maybe involving myVar myVar = 5
For example, let's define a function that will add 5 to the passed argument and then return it.
local function addFive(n) return n + 5 end
Now, we can call our function (in the same scope as that we declared it) by it's name:
local number = 8 number = addFive(number) print(number) -- prints 13
Functions can also call other functions, like
print(), for example:
local function coolFunction(thing) print("I am coolFunction and I was just called!") print("By the way, you passed", thing, "to me.") end coolFunction("Hello World")
I am coolFunction and I was just called! By the way, you passed Hello World to me.
Functions can also be called multiple times. Take this example below:
local function myFunction() print("Hello World!") end myFunction() myFunction() myFunction()
Hello World! Hello World! Hello World!
Functions can also call themselves, this is called a recursive function:
local function fibRecursive(a, b, n) if n > 0 then return fibRecursive(b, a + b, n - 1) else return a end end local function fibonacci(n) return fibRecursive(0, 1, n) end print(fibonacci(7)) -- 13 print(fibonacci(12)) -- 144
Warning: Improper recursion can result in runtime errors when the call stack is exceeded. Always remember to use proper tail calls wherever possible when using recursion.
Due to the first class nature of functions, they can even be arguments of other functions. For example:
local function applyHelloWorld(func) func("Hello World!") end -- Pass Lua's builtin print function... applyHelloWorld(print)