Lua for Perlmongers
Lua
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 lua.org
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.
perl.org:
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
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.
Syntax
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
mt.ping = 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
Environments
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
http://luarocks.org/repositories/rocks/ ~ 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.
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.
“embeddable”
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
Timeline
1986
1987 Perl, Bash
1988 Tcl
1989
1990
1991 Python, VB
1992 S-lang
1993 Lua
1994
1995 Ruby, Javascript, PHP
1996