A quick guide to Lua

First of all, look at "Programming in Lua" at http://www.lua.org/pil/ . Read up on tables, as these are the basic type for everything in Lua.

But, if you want a a quick start, here you go:


Statements in Lua have no braces or semicolons, and whitespace is not significant. Instead, statements like if ... then use end to terminate a block. Example:
--print something out!
if note==5 then
   print("Note was five!")
Note that comments begin with two dashes.


Lua's basic types are numbers (Lua does not distinguish between integers and floats), strings (which are immutable) and tables, which are used for all data structures. Lua is dynamically-typed, and variables are not declared before use. Simply assign to them to start using them.

NOTE: by default all Lua variables are global! To use a local variable, you must declare it using local:
x = 5

function dostuff()
    x = x + 1 -- changes global x
    local y
    y = 5     -- y is only visible in this scope

Any parameters are automatically local, as are variables used in for loops (see later).

Numbers are pretty standard. +,-,*,/,%,^ can all be used to manipulate them (^ is exponentation, not XOR).

Comparisons are like most other languages.

Strings are also fairly standard. They can concatenated with ... Slices can be made with string.sub(string, start, end). There is some support for pattern matching/replacement, but not full regexp support.


Lua functions are defined with the function keyword and are terminated with end. Example:
function dosomething(x,y,z)
    print("X is "..x.." and y is "..y.." and z is "..z)
Functions are first class in Lua, so you can store them in tables (you can even index tables with functions!).
function do_something_one(one, two)

function do_something_two(one, two)

ftable = {one = do_something_one, two = do_something_two}

ftable.one("hello", "there")
ftable.two("hello", "there")

Note for functional programmers: Lua supports closures and anonymous functions:
function returnfunc(y)
    local x = 10
    return function() print(x) x = x + y end

z = returnfunc(1)
z() -- prints 10
z() -- prints 11
z() -- prints 12

z = returnfunc(3)
z() -- prints 10
z() -- prints 13
z() -- prints 16


Tables are actually hashtables and can be indexed with any Lua type, not just integers. They are extremely powerful and form Lua's basic data type. Tables can be constructed literally:
notes = {C=0, D=2, E=4, F=5}
If the index is a string you can use . notation as in notes.C or you can use square brackets: notes["C"]
If you don't specify keys:
notes = {0,2,4,5}
tables will be indexed like an array (but starting at 1 (one) not zero -- Lua is always 1-indexed). So you can do
Lua automatically converts strings to numbers and vice-versa, so it is safe to concatenate a number and a string together.
You could also specifically give numerical indices:
notes = {[1]=0, [7]=2, [13]=4,[19]=5}
But note that you must put [] around the keys in this case. Tables are always accesed by reference, not value (the same is true for strings, but since they are immutable, this is of little consequence). If you want a copy, you need to write a copy function!

Tables can be nested. This makes it easy to represent things like lists:

function addToList(element, list)
    --list must be a list or nil
    if not list then
        return {head=element, tail=nil}
        addToList(list.tail, element)    

function printList(list)
    if not list then 
        print(list.head.." ")

l = addToList(1) --nb: omitted parameters just become nil

printList(l) -- result: 1 2 3


Simple for loops are easy:
for i=1,10 do
 ... stuff ..
You can give a third parameter if you want to specify a step:
for i=1,10,2 do
while loops are easy too:
x = 0
while x<5 do
    x = x + 1
Note that you need to have the do at the end of the while statement! There's also repeat...until:
x = 0
   x = x + 1
until x==5
To iterate over a table, use pairs:
for key,value in pairs(notes) do
    vprint(key.." = "..value)
If you want to iterate over numerical keys in order, use ipairs:
for i, value in ipairs(notes) do
    vprint(i.." = "..value)
This will ignore any non-numeric keys but will iterate through the numerical ones in ascending order.