oreilly.comSafari Books Online.Conferences.


Introducing Lua

by Keith Fieldhouse

There's no reason that web developers should have all the fun. Web 2.0 APIs enable fascinating collaborations between developers and an extended community of developer-users. Extension and configuration APIs added to traditional applications can generate the same benefits.

Of course, extensibility isn't a particularly new idea. Many applications have a plugin framework (think Photoshop) or an extension language (think Emacs). What if you could provide a seamlessly integrated, fully dynamic language with a conventional syntax while increasing your application's size by less than 200K on an x86? You can do it with Lua!

Lua Basics

Roberto Ierusalimschy of the Pontifical Catholic University of Rio de Janeiro in Brazil leads the development of Lua. The most recent version (5.0.2; version 5.1 should be out soon) is made available under the MIT license. Lua is written in 99 percent ANSI C. Its main design goals are to be compact, efficient, and easy to integrate with other C/C++ programs. Game developers (such as World of Warcraft developer Blizzard Entertainment) are increasingly using Lua as an extension and configuration language.

Virtually anyone with any kind of programming experience should find Lua's syntax concise and easy to read. Two dashes introduce comments. An end statement delimits control structures (if, for, while). All variables are global unless explicitly declared local. Lua's fundamental data types include numbers (typically represented as double-precision floating-point values), strings, and Booleans. Lua has true and false as keywords; any expression that does not evaluate to nil is true. Note that 0 and arithmetic expressions that evaluate to 0 do not evaluate to nil. Thus Lua considers them as true when you use them as part of a conditional statement.

Finally, Lua supports userdata as one of its fundamental data types. By definition, a userdata value can hold an ANSI C pointer and thus is useful for passing data references back and forth across the C-Lua boundary.

Despite the small size of the Lua interpreter, the language itself is quite rich. Lua uses subtle but powerful forms of syntactic sugar to allow the language to be used in a natural way in a variety of problem domains, without adding complexity (or size) to the underlying virtual machine. The carefully chosen sugar results in very clean-looking Lua programs that effectively convey the nature of the problem being solved.

The only built-in data structure in Lua is the table. Perl programmers will recognize this as a hash; Python programmers will no doubt see a dictionary. Here are some examples of table usage in Lua:

a      = {}       -- Initializes an empty table
a[1]   = "Fred"   -- Assigns "Fred" to the entry indexed by the number 1
a["1"] = 7        -- Assigns the number 7 to the entry indexed by the string "1"

Any Lua data type can serve as a table index, making tables a very powerful construct in and of themselves. Lua extends the capabilities of the table by providing different syntactic styles for referencing table data. The standard table constructor looks like this:

t = { "Name"="Keith", "Address"="Ballston Lake, New York"}

A table constructor written like

t2 = { "First", "Second","Third"}

is the equivalent of

t3 = { 1="First", 2="Second", 3="Third" }

This last form essentially initializes a table that for all practical purposes behaves as an array. Arrays created in this way have as their first index the integer 1 rather than 0, as is the case in other languages.

The following two forms of accessing the table are equivalent when the table keys are strings:

t3["Name"] = "Keith"
t3.Name    = "Keith"

Tables behave like a standard struct or record when accessed in this fashion.

Variations on a Theme

The following variations on the venerable "Hello World" program illustrate the malleable and extensible nature of the language. First, the minimal implementation:

print("Hello World")

Here's a function declaration that accepts the name of the person to greet. The double "dot" operator does string concatenation:

function sayhello(person)
   print("Hello "..person)

This form of function definition masks a powerful feature of Lua: functions themselves are first-class data types. The underlying form of function definition is actually the following:

sayhello = function(person) 
    print("Hello "..person)

You may assign functions to variables, pass them to other functions as parameters, place them in tables, and generally deal with them in the same way as any other Lua value. Functions in Lua do not have names. Rather, you apply the () operator to variables that hold function references in order to call the function. To call a function reference stored in a table element, use the following:

t = {}
function t.sayhello(name)
    print (


This starts to look a lot like a method invocation except that there's no self or this reference for the function to access. Lua takes care of this by adding another piece of syntactic sugar, the : operator. Referencing the table element with a : instead of a . causes Lua to automatically pass a parameter, self, to the function. So:

t      = {}
t.Name = Fred

function t:sayhello()
   print (Hello..self.Name)

-- Or, other expressions that mean the same thing:

This is object encapsulation: a way to combine an object's data with the code that operates on that data. Thus far, there isn't any way to create instances of an object. You must assemble objects by hand individually.

Lua uses a powerful meta table concept that among other things can bridge this final gap to object oriented programming (still without changing the underlying VM). A meta table is a Lua table that has been attached to a given table with the setmetatable built-in function. Lua uses the meta table for certain special functions that control how its associated table behaves.

Producing Open Source Software

Related Reading

Producing Open Source Software
How to Run a Successful Free Software Project
By Karl Fogel

Pages: 1, 2, 3

Next Pagearrow

Sponsored by: