This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.
Programming in Lua | ||
Part I. The Language Chapter 6. More about Functions |
An obvious consequence of first-class functions is that we can store functions not only in global variables, but also in table fields and in local variables.
We have already seen several examples of functions in table fields:
Most Lua libraries use this mechanism
(e.g., io.read
, math.sin
).
To create such functions in Lua,
we only have to put together the regular syntax for functions and
for tables:
Lib = {} Lib.foo = function (x,y) return x + y end Lib.goo = function (x,y) return x - y endOf course, we can also use constructors:
Lib = { foo = function (x,y) return x + y end, goo = function (x,y) return x - y end }Moreover, Lua offers yet another syntax to define such functions:
Lib = {} function Lib.foo (x,y) return x + y end function Lib.goo (x,y) return x - y endThis last fragment is exactly equivalent to the first example.
When we store a function into a local variable we get a local function, that is, a function that is restricted to a given scope. Such definitions are particularly useful for packages: Because Lua handles each chunk as a function, a chunk may declare local functions, which are visible only inside the chunk. Lexical scoping ensures that other functions in the package can use these local functions:
local f = function (...) ... end local g = function (...) ... f() -- external local `f' is visible here ... endLua supports such uses of local functions with a syntactic sugar for them:
local function f (...) ... end
A subtle point arises in the definition of recursive local functions. The naive approach does not work here:
local fact = function (n) if n == 0 then return 1 else return n*fact(n-1) -- buggy end endWhen Lua compiles the call
fact(n-1)
,
in the function body,
the local fact
is not yet defined.
Therefore, that expression calls a global fact
,
not the local one.
To solve that problem,
we must first define the local variable
and then define the function:
local fact fact = function (n) if n == 0 then return 1 else return n*fact(n-1) end endNow the
fact
inside the function refers to the local variable.
Its value when the function is defined does not matter;
by the time the function executes,
fact
already has the right value.
That is the way Lua expands its syntactic sugar for local functions,
so you can use it for recursive functions without worrying:
local function fact (n) if n == 0 then return 1 else return n*fact(n-1) end endOf course, this trick does not work if you have indirect recursive functions. In such cases, you must use the equivalent of an explicit forward declaration:
local f, g -- `forward' declarations function g () ... f() ... end function f () ... g() ... end
Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved. |