Lua for Perlmongers


A scripting language. designed by Roberto Ierusalimschy and others at the Pontifical Catholic University of Rio de Janeiro (PUC-Rio). Widely used in big games and small devices They say: “Only language developed outside an industrialised country to achieve global relevance”

Lua according to

They also say:
Lua is a powerful, fast, lightweight, embeddable scripting language. Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.

Lua on Lua decoded

Lua is a powerful, fast, lightweight, embeddable scripting language.what it wants to be Lua combines simple procedural syntax with powerful data description constructs based on associative arrays like Javascript and extensible semantics. not mentioning objects Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, like Parrot and has automatic memory management with incremental garbage collection, not reference counting, as is common making it ideal for configuration, scripting, and rapid prototyping. Flexible & Powerful| 20,000 CPAN modules That's why we love Perl

Data types

Lua has 8 types: table the aforementioned “associative array”, like a perl hash number all numbers are 64 bit floating point (like Javascript) string 8 bit, encoding agnostic function boolean nil userdata undifferentiated blobs, usually C structs thread coroutines, not system level threads Perl has at least 4 types, depending on what you count.


Tables are the only collection typelike Javascript a = {} --> empty table; my $a = {} b = {pi=3.14; e=2.7, semicolons or commas allowed c = 'hello',} --> a table with 3 entries b['3 toed'] = a --> keys needn't fit constructor syntax b[13] = 0 b.width = 7 --> syntax sugar: attributes are members print(b.e + b['width']) --> 9.7like Javascript b['pi'] = nil --> delete $b->{'pi'} b = nil --> undef $b nil is deadly Every namespace is a table

Tables behaving like arrays

Lua has syntax sugar and functions to make tables look like arrayslike Javascript c = {'cat', 'dog', 'fish'} --> c[1] == 'cat'one based indexing d = {'cat', pi=3.1, 'dog'} --> d[2] == 'dog'; d['pi'] == 3.1 print(#d) --> 2# is the length operator d[3] = d.pi --> length is now 3 d[0] = 'pelican' --> length is still 3 d[7] = 'an isolated numeric key' --> length is still 3 It is easy to process contiguous numeric keys from 1..n: for i, v in ipairs(d) do -- something end Javascript, the mostly good bits, with Pascal syntax

Other types

Perlish number/string coercion:Lua authors: “we are not sure this was a good idea...” "0" + 4 --> 4 "0" .. 4 --> '04' .. is string concatenation verb "2" does not equal 2. “not equal” is spelt ~= nil and false are false. Everything else is true. 0 and "" and {} are true. Functions can be declared in two ways: function concat(a, b) return a .. b end -- this way is syntax sugar concat = function(a, b) return a .. b end like Javascript again Functions have environments, tables and userdata have metatables.


Semicolons are optional not implicit, optional -- unlike Javascript a = 1 b =2 c = 3 print ("hello") is the same as a, b, c = 1, 2, 3; print("hello") Most operators are familiar, but 2 ^ 3 --> exponentiation, like 2 ** 3xor is written 'xor' function f(...) print(...) end--> ... represents varargs (like @_)

long strings, function sugar, fleeting lists

[[this is a long string literal]] [==[ this is a string literal containing these ]] that would end some strings ]===], but not this ]==] brackets and any number of equals signs -- a comment to the end of the line --[=[ a multi-line comment ]=] When a function is given one literal string or table, the brackets are optional. print{} print '' print[=[ ]=] Functions can return multiple values: Sometimes those lists are collapsed; Sometimes they are truncated to one value. like perl lists, but different rules

Loops, conditionals, blocks

while something do stuff end repeat stuff until condition -->block scope ends after until for i = 1, 9 do print(i) end --> foreach $i (1 .. 9){print $i} for i = 9, 1, -2 do print(i) end --> for ($i = 9; $i >= 1; $i -= 2){...} for x in expression do f(x) end -- iterate over somethingcomplex semantics if x then stuff elseif y then stuff else stuff end -- also and and or short-circuit return and break must be at the end of a block so you go do break end Variables are global by default, lexically scoped with local. like Javascript

Metatables, objects

Things have metatables that contain magical Metamethods. metatables are plain Lua tables __add = function(self, other) -- coerce to number and add __lt = function(self, other) -- true if self < other __call = function(self, ...) -- do this if treated like a function You can alter a metatable in place or, for tables, replace it altogether. x, mt = {}, {} setmetatable(x, mt) mt.__index = mt where to look for attributes = function(self)print self end -- function mt:ping()print self endsyntax sugar for the same x:ping() --> table: 0x1c119c0 x:y(...) --> x.y(self, ...) y.setmetatable(mt) -- so y is another one


Functions, threads and userdata also have environments. An environment is a containing scope. Environments are tables. You can change or replace a function's environment. change without replacement affects others You can turn a function into a closure after the fact You can mess with your coroutines.

threads are coroutines

(“one-shot continuations”) co = coroutine.create( co is a thread object function(a, b) -- do stuff d, e = coroutine.yield(a, b, c) -- do stuff, etc h = coroutine.yield(f, g) end) x, y, z = coroutine.resume(co, u, v)x, y, z are a, b, c yielded above; u, v go to d, e x, y = coroutine.resume(co, w) y, z are f, g; w goes to h

Standard library

In core namespace: Boring useful functions: assert, print, tostring, etc. Table manipulation functions: next, pairsipairs Module loading functions. metatable/environment setting/getting. coroutine.* for threads package.* for modules and packages string.* for string manipulation including “patterns” -- regexps that use % instead of \ table.* more table functions math.* io.* files are opened as objects with methods os.* time and a few other things debug.*

luarocks: another CPAN wannabe ~ a few hundred packages LPeg, Fancy Parsing Expression Grammers parsing, like perl6 grammars Coat, OO model based indirectly on Moose wrappers around popular C libraries. a web stack (from tcp up) that nobody much uses.

“fast, lightweight”

From Perl wins with tr///. Lua wins with arithmetic.

LuaJIT vs Perl

tr/// still wins. Even with JIT, Lua generally uses less memory in artificial benchmarks.

Speed vs other languages

LuaJIT is as fast as Java.


Perl is embeddable, too. Lua's approach is: be as small as possible be pure ANSI C with no #ifdefs talk to C through a single stack. Lua objects are inaccessible to C The API makes leaking memory hard, at the cost of expressiveness. People have embedded Lua in Perl but Ubuntu only has libluabridge-ruby

Documentation size as simplicity metric

package compressed uncompressed lua5.1-doc 103k 586k perl-doc 7161k 13.4M rubybook 411k 2384k tcl8.4-doc 982k 1319k bash-doc 1215k 2503k python2.6-doc 5619k 30.7M plt-scheme-doc 8211k 81.7M Lua's language, C API, and standard library reference is a 250kB html file


1986 1987 Perl, Bash 1988 Tcl 1989 1990 1991 Python, VB 1992 S-lang 1993 Lua 1994 1995 Ruby, Javascript, PHP 1996