Seminar slides
This page contains the slides of a talk about Lua
given at the
Software Engineering Lab
of the
University of Waterloo
in November 1995.
At that time, the current version of Lua was
2.4
and so these slides are somewhat outdated:
for instance,
fallbacks were replaced by tag methods in
3.0
and by metatables in
5.0,
and the C API changed in
4.0.
Nevertheless,
the main points remain valid.
Lua, an extensible extension language
by
Luiz Henrique de Figueiredo,
Roberto Ierusalimschy,
Waldemar Celes
Abstract.
There is an important trend nowadays to split complex systems in two
parts: kernel (written in a compiled language) and configuration
(written in an interpreted language). Lua is a new language for
configuring and extending applications, Lua combines procedural
features with powerful data description facilities, by using a
simple, yet powerful, mechanism of tables. This mechanism implements
the concepts of records, arrays, and recursive data types (pointers),
and adds some object-oriented facilities, such as methods with
dynamic dispatching.
Lua presents a mechanism of fallbacks that allows programmers to extend
the semantics of the language in some unconventional ways. As a
noteworthy example, fallbacks allow the user to add different kinds of
inheritance to the language.
Currently, Lua is being extensively used in production for several
tasks, including user configuration, general-purpose data-entry,
description of user interfaces, storage of structured graphical
metafiles, and generic attribute configuration for finite element
meshes. Lua is also being used in several research projects, such as
"active" graphical objects, computing with distributed objects, and
transparently extending WWW browsers with client-side code.
- increasing demand for customization
- choosing parameters no longer enough
- configuration decisions at run time
- macros and scripts increase productivity
- flexible user interfaces
- current design trend: split
- kernel
- basic classes and objects
- compiled code
- configuration
- connects classes and objects
- interpreted code
- cleaner, more flexible design
- proliferation of little languages
- preference selection
- option lists in command lines
- configuration files: variable-value pairs
- scripting languages
- task automation with limited flow control
- macro languages
- task automation with no flow control
- embedded languages
- user defined functions
- primitives provided by applications
- extend kernel semantics
- not standalone, need host client
- host provides domain-specific extensions
- customizes embedded language
- higher level abstractions
- single syntactical framework
- syntax for own programs
- API for interfacing with hosts
- for application programmer
- two-way communication
- good data description facilities
- simple syntax and semantics
- main users not professional programmers
- small with small implementation
- programming-in-the-small
- many mechanisms not essential
- extensibility
- very high abstraction levels
- many different domains
- Computer Graphics Technology Group of PUC-Rio, Brazil
- Began as partnership between PUC-Rio and PETROBRAS
- Now has many industrial partners
- Main area: Computer Graphics
- Scientific visualization
- Graphical user interfaces
- Geometric modeling
- Major concern: portability
- clients use many different platforms
- need for configuration scheme
- generic data entry for pre-processing
- simple declarative language
- pre-coded validation tests not adequate
- users demanded procedural power
- report generator for lithology profiles
- declarative language for data description
- design single generic language: Lua
- procedural language
- data description facilities
- extensible language framework
- general purpose extension language
- simplified Pascal-like syntax
- procedural programming
- powerful data description facilities
- small library of C functions
- 6000 lines (2000 from yacc)
- bytecode compiler and interpreter
- predefined functions
- additional client libraries
- extensible with meta-mechanisms
- dynamic associative arrays
- reflexive facilities
- fallbacks
- 100 line header file; 30 C functions
- interface uses only simple types
- numbers, strings, pointers
- Host can run Lua code in file or string
- all chunks run in a global environment
- Host can read/write global variables in Lua
- Host can call Lua functions
- Lua can call registered Host functions
- Lua is dynamically typed
- only values have types, variables don't
- no variable type declarations
- Lua has garbage collection
- unused values are discarded
- no need for explicit memory management
- primitive data types
- nil
- numbers and strings
- functions: provided by user or host
- tables: associative arrays
- userdata: pointers to host data
- "user types"
- can be indexed with any value
- ordinary arrays, sets, symbol tables, ...
- can simulate records
- a.name is syntactic sugar for a["name"]
- values are references to objects
- tables can model generic graphs
- need to be explicitly created
- many algorithms are simplified
- built-in data structures for searching
- unifying data constructor
- support for objects
- lists
colors = {"red", "green", "blue", "black"}
colors = {}
colors[1]="red" colors[2]="green"
colors[3]="blue" colors[4]="black"
- records
w = {x=200, y=300, color="blue"}
w = {} w.x=200 w.y=300 w.color="blue"
- user controlled type constructors
- f{...} is syntactic sugar for f({...})
w = Window{x=200, y=300, color="blue"}
- function type returns type of a value
- function nextvar traverses global variables
- manipulation of global environment
i,v = nextvar(nil)
while i do
...
i,v = nextvar(i)
end
- function next traverses tables
i,v = next(t,nil)
while i do
...
i,v = next(t,i)
end
function save(i,v)
local t=type(v)
write(i..'=')
if t=='nil' then write('nil')
elseif t=='number' then write(v)
elseif t=='string' then write('"'..v..'"')
elseif t=='table' then write_record(v)
end
end
function write_record(t)
local i,v=next(t,nil)
write('{')
while i do
save(i,v)
i,v=next(t,i)
if i then write(',') end
end
write('}')
end
writeto("state") -- save env to file
i,v=nextvar(nil)
while i do
save(i,v) i,v=nextvar(i)
end
dofile("state") -- restore env from file
- functions called when Lua cannot proceed
- halting unsuitable for embedded language
- semantics
- exception handling with resumption
- pragmatics
- meta-mechanism for language extension
- typical uses
- different kinds of inheritance
- overloading
function Index(t,f)
if f=="parent" then
return oldIndex(t,f)
end
local p=t.parent
if type(p)=="table" then
return p[f]
else
return oldIndex(t,f)
end
end
oldIndex=setfallback("index", Index)
a=Window{x=100, y=200, color="red"}
b=Window{x=300, y=400, parent=a}
b.color == "red"
familiar syntax for computing with application objects
function Overload(a,b,op)
local i=op.."("..a.name..","..b.name..")"
if T[i]==nil then
n=n+1 T[i]=create("t"..n)
write(T[i].name..'='..i.."\n")
end
return T[i]
end
function create(v)
local t={name=v}
setglobal(v,t)
return t
end
setfallback("arith",Overload)
create("a") create("b") create("c")
n=0 T={}
E=(a*a+b*b)*(a*a-b*b)/(a*a+b*b+c)+(a*(b*b)*c)
t1=mul(a,a) t2=mul(b,b) t3=add(t1,t2)
t4=sub(t1,t2) t5=mul(t3,t4) t6=add(t3,c)
t7=div(t5,t6) t8=mul(a,t2) t9=mul(t8,c)
t10=add(t7,t9)
global common sub-expression identification!
- Lisp dialects (Scheme)
- simple, easily parsed syntax
- built-in extensibility
- unfriendly for non-programmers
- Tcl
- success due to Tk
- very primitive syntax
- single primitive type (strings)
- no built-in control structures
- inefficient
- Python
- not ready for embedding (no prefix!) [This has been corrected.]
- not small (programming-in-the-large)
- Lua
- 10 to 20 times faster than Tcl
- 20 times slower than C
- small library; single, 100 line header file
- pre-compiled to bytecodes
- clean but familiar syntax
- simple, extensible semantics
- built-in notion of objects
- single data structure mechanism (tables)
- portable (DOS, Win, Mac, Unix, CRAY)
- secure interpreters
- freely available (but not public domain)
- extensively used in production since mid 93
- configuration of application environments
- general-purpose data-entry with user defined dialogs and validation procedures
- description of user interfaces (IUP-Lua)
- storage of structured graphical metafiles
- generic attribute configuration for FEM
- research projects
- visual programming system: Visual Lua
- "active" graphical objects
- computing with distributed objects
- transparently extending WWW browsers with client-side Lua code
lua_Object lua_setfallback (char *name, lua_CFunction fallback);
void lua_error (char *s);
int lua_dofile (char *filename);
int lua_dostring (char *string);
int lua_callfunction (lua_Object function);
int lua_call (char *funcname);
void lua_beginblock (void);
void lua_endblock (void);
lua_Object lua_getparam (int number);
#define lua_getresult(_) lua_getparam(_)
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
void *lua_getuserdata (lua_Object object);
void lua_pushnil (void);
void lua_pushnumber (float n);
void lua_pushstring (char *s);
void lua_pushliteral (char *s);
void lua_pushcfunction (lua_CFunction fn);
void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
lua_Object lua_getglobal (char *name);
void lua_storeglobal (char *name);
void lua_storesubscript (void);
lua_Object lua_getsubscript (void);
int lua_type (lua_Object object);
int lua_lock (void);
lua_Object lua_getlocked (int ref);
void lua_pushlocked (int ref);
void lua_unlock (int ref);
lua_Object lua_createtable (void);