Introdução a Lua,
LuaOrb e O
2
Renato Cerqueira
Agenda
•
O que é Lua?
•
Por que Lua?
•
Como é Lua?
•
LuaOrb
O Que é Lua?
•
Yet Another Scripting Language
• Da mesma família de Perl, Tcl, Python, Ruby, JavaScript, etc
•
Uma linguagem para a descrição de dados
• Capacidade de expressão similar de XML
•
Uma linguagem embutida (embeddable)
•
Simples e flexível
• “Coisas simples são simples, coisas complexas são possíveis”
Por que Lua?
•
Leve
• uma linguagem simples e pequena, com poucos conceitos
• núcleo com aprox. 60K, executável completo com 140K
•
Portável
• escrita em ANSI C clean
• executa em PalmOS, EPOC (Symbian), Brew (Qualcomm),
Playstation II, XBox, sistemas embutidos, mainframes, etc.
•
Eficiente (ver benchmarks)
•
Fácil de ser embutida
Lua é Pequena
•
Tamanhos de algumas linguagens (Solaris)
• Lua 4.0: 120K
• Tcl (? < 8.0): 655K (~ 5x)
• Python 2.0: 860K (~ 6.5x)
• Perl 5.6: 1.1M (~ 8.5x)
•
Seu tamanho pequeno tem outros benefícios:
• Fácil de instalar
• Fácil de adaptar
Lua é Eficiente
•
Mais rápida que Perl, Python; muito mais rápida que
Tcl
• Ver www.bagley.org/~doug/shootout
•
Eficiente para descrição de dados
• Compilador rápido
•
Fácil de ser embutida em C/C++
Mais Resultados
•
Computer Language Shootout Scorecard
• http://dada.perl.it/shootout/
•
Comparações
• Tempo de CPU
• Uso de memória
Algumas Aplicações
•
Jogos
• LucasArts, BioWare, Microsoft, Relic Entertainment, Absolute
Studios, Monkeystone Games, etc.
•
Outros usos
• tomsrtbt: ”The most Linux on one floppy disk”
• Crazy Ivan Robot (campeão das RoboCup 2000 e 2001 na
Dinamarca)
• Sistema de monitoramento de pacientes com PDAs (InCor)
• Layout de chips (Intel)
• APT-RPM (Conectiva e United Linux)
• Space Shuttle Hazardous Gas Detection System (ASRC
Enquete na gamedev.net
Which language do you use for scripting in your game engine?
31 4.51% Other 4 0.58% TCL 8 1.16% Ruby 9 1.31% Perl 10 1.45% Lisp 48 6.98% Python 67 9.75% C (with co-routines) 141 20.5% Lua 181 26.3% I made my own 188 27.3%
Evolução da Linguagem
•
Diretrizes • Simplicidade • Eficiência • Portabilidade • Extensibilidade•
Versão 1.0 • Descrição de dados • Recursos básicos de processamento•
Versão 2.0 • Mecanismos de extensibilidade•
Versão 3.0• Melhor e mais extensibilidade
function fat (n) if n == 0 then return 1 else return n*fat(n-1) end end
Como é Lua?
•
Sintaxe similar a Pascal
•
Tipagem dinâmica
•
Gerenciamento de memória
automático
• Estruturas de dados dinâmicas
• Coleta de lixo
•
Sete tipos básicos
• números, booleanos, tabelas,
Strings
•
No size limits, good performance for long strings
• common practice to read a whole text file in a single string
before processing
•
Strings can store arbitrary binary data
• not ‘\0’ terminated
•
Pattern matching facilities, implemented through a
standard library
Example: Decoding a URL
encoding string
•
This function is used by CGILua to decode a URL encoding string:• “lua%3Dis+great” → “lua=is great”
Tables
•
Implement associative arrays
• any value (including functions and other tables) can be used
both for indices and values
•
Grow and shrink dynamically
• without generating garbage
•
Referential semantics
•
Tables implement most common data structures easily
and efficiently
Tables x Data Structures
•
arrays: numbers as keys• very efficient
• algorithm to store arrays as arrays!
•
records: literal strings as keys• sugar: a.x ≡ a["x"]
•
sets: values as keysConstructors
•
Expressions to create and initialize tables
•
Record style
point = {x=10, y=20}
print(point.y) --> 20
days = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"} print(days[3]) --> Tue
points = {{x=0,y=0}, point; n=2}
•
List style
Constructors
•
Data description uses:
book{
author="F.P.Brooks",
title="The Mythical Man-Month", year=1975,
}
book{
author="Jon Bentley",
title = "Programming Pearls",
year=1986, }
Tables x Objects
•
Tables are dynamically created objects
value = v
next =
list
old list
...
Functions
•
First class values
function inc (x) return x+1 end inc = function (x) return x+1 end sugar function count (x)
return function () x = x+1; return x; end end
a = count(10)
Lexical Scoping
function newObject () local x
local get_x = function () return x end
local set_x = function (new_x) x = new_x end return {
get_x = get_x, set_x = set_x }
end
Objects
•
First class functions + tables = almost OO.
• tables can have functions as field values (≅ methods)
•
Syntactic sugar for defining and calling methods
• handles hidden parameter self
Metatables
•
Metatables redefine the behavior of tables (and
userdata)
•
Typical example: inheritance (delegation)
• field “index” in its metatable drives how a table handles absent
indices
• it can be a table (straight delegation) or a function (generic
Inheritance (delegation)
b = Class:new{} print(b.x) -> 0 b:add(20) print(b.x) -> 20 Class = {x = 0} Class.__index = Class function Class:add (d) self.x = self.x + d endfunction Class:new (o) setmetatable(o, self) return o
look for “index” at the
Inheritance (delegation)
b:add(20) → b.add(b, 20) → b[“add”](b, 20) b.[“add”] → nil ?
metatable(b).__index[“add”] → Class.index[“add”] →
Class[“add”] → <method add>
Coroutines
•
simple (and portable) alternative for multi-threading
•
powerful mechanism per se
• generators, “pipes”, simulation, etc.
•
Implemented as semi-coroutines
• coroutine.create
Multithreading Non-Preemptive
require “luasocket” host = “www.w3.org” file = “/TR/REC-html32.html” c = assert(socket.connect(host,80)) c:send(“GET “..file..”\n”) while true dolocal s, status = c:receive(2^10) io.write(s)
if status == “closed” then break end end
Multithreading Non-Preemptive
function download(host,file) local c = assert(socket.connect(host,80)) local count = 0 c:send(“GET “..file..”\n”) while true dolocal s, status = Receive(2^10) count = count + string.len(s)
if status == “closed” then break end end
c:close()
Multithreading Non-Preemptive
-- sequential version function Receive(connection) return connection:receive(2^10) end -- concurrent version function Receive(connection) connection:timeout(0)local s, status = connection:receive(2^10) if status == “timeout” then
coroutine.yield(connection) end
Multithreading Non-Preemptive
threads = {}function get (host,file)
Multithreading Non-Preemptive
function dispatcher() while true do
local n = table.getn(threads) if n == 0 then break end
local connections = {} for i=1,n do
local status, res = coroutine.resume(threads[i]) if not res then
LuaOrb
•
Binding between Lua and several middleware systems
• CORBA, COM, “Java”
•
Dynamic binding, based on reflexivity
•
Flexible type mapping
• straightforward for arrays, records, strings, primitive types
obj = luaorb.createproxy(“corbaloc::hostname:6666/Id”, “InterfaceName”)
LuaOrb: Example
obj = lo.createproxy(“corbaloc:...”) obj:foo({x=10, y=20}, {1,2,3})
obj.foo(obj, {x=10, y=20}, {1,2,3})
- invoke metatable
- try to find method “foo” - return closure
- invoke closure, which:
- convert values to expected types - invoke method
- convert returned value (if any) returns a proxy
LuaOrb: Servers
•
Objects created in Lua may be exported to the outside
world
• needs an explicit type
•
Implementation needs a “generic adaptor”, to dispatch
methods
• In CORBA, uses the Dynamic Skeleton Interface
• In Java, needs dynamic code generation (as of version ?)