get started with lua - hackference 2016
TRANSCRIPT
Get started with
Etiene Dalcol @etiene_d
@etiene_dHackference 2016
@etiene_d
@etiene_dHackference 2016
@etiene_dHackference 2016 luaconf.com
@etiene_dHackference 2016
What’s Lua
Why Lua
Key Concepts
@etiene_dHackference 2016
@etiene_dHackference 2016
• Dynamic duck-typed language • Multi-paradigm
• procedural, OO, functional
• Garbage collection • Coroutines • First-class functions • Lexical scoping • Proper tail calls • MIT License
What is Lua?
@etiene_dHackference 2016
Why Lua?
Powerful.
@etiene_dHackference 2016
Why Lua?Size
(docs included)
First-class functions+
Lexical scoping +
Metatables
Native C API
276 Kb
Object Orientation
Ada, Fortran, Java, Smalltalk, C#, Perl,
Ruby etc.+
@etiene_dHackference 2016
Simple.Powerful.
Why Lua?
@etiene_dHackference 2016
_G _VERSION assert collectgarbage dofile error getmetatable ipairs load loadfile next pairs pcall print rawequal rawget rawlen rawset require select setmetatable tonumber tostring type xpcall bit32.arshift bit32.band bit32.bnot bit32.bor bit32.btest bit32.bxor bit32.extract bit32.lrotate bit32.lshift bit32.replace bit32.rrotate bit32.rshift
coroutine.create coroutine.resume coroutine.running coroutine.status coroutine.wrap coroutine.yield debug.debug debug.getuservalue debug.gethook debug.getinfo debug.getlocal debug.getmetatable debug.getregistry debug.getupvalue debug.setuservalue debug.sethook debug.setlocal debug.setmetatable debug.setupvalue debug.traceback debug.upvalueid debug.upvaluejoin io.close io.flush io.input io.lines io.open io.output io.popen io.read io.stderr io.stdin io.stdout io.tmpfile io.type io.write
file:close file:flush file:lines file:read file:seek file:setvbuf file:write math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.cosh math.deg math.exp math.floor math.fmod math.frexp math.huge math.ldexp math.log math.max math.min math.modf math.pi math.pow math.rad math.random math.randomseed math.sin math.sinh math.sqrt math.tan math.tanh
os.clock os.date os.difftime os.execute os.exit os.getenv os.remove os.rename os.setlocale os.time os.tmpname package package.config package.cpath package.loaded package.loadlib package.path package.preload package.searchers package.searchpath string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper table.concat table.insert table.pack table.remove table.sort table.unpack
@etiene_dHackference 2016
Hackference 2016 @etiene_d
"Since Lua itself is so simple, it tends to
encourage you to solve problems simply."
Ragnar Svensson - Lead Developer at King (Lua Workshop Oct 15 2015)
@etiene_dHackference 2016
Fast.Simple.Powerful.
Why Lua?
@etiene_dHackference 2016
http://www.humbedooh.com/presentations/ACNA%20-%20mod_lua.odp Introducing mod_lua by Daniel Gruno
@etiene_dHackference 2016
My Reasons
• It looks cool (I heard you could make games with it)
Better
@etiene_dHackference 2016
Better Reasons
• It looks cool (I heard you could make games with it)
• It’s made in my home country (In my university to be more precise)
@etiene_dHackference 2016
• It looks cool (I heard you could make games with it)
• It’s made in my home country (In my university to be more precise)
• It’s easy to learn
Better Reasons
@etiene_dHackference 2016
• The index starts at 1 • There’s no continue • The non-equality operator is ~= • null is nil • Comments are - - • Only nil and false are equivalent to false • Functions can genuinely return multiple values • Variables are global by default • Pattern matching is not regular expression • The concatenation operator is ..
What’s different
@etiene_dHackference 2016
Quick idioms
• a, b = b, a
• There’s no ternary operator but you can return x==1 and “yes” or “no”
• The access to local variables is faster than to global local match = string.match
@etiene_dHackference 2016
Using Lua: three approaches
Embedded Scripting General-purpose
@etiene_dHackference 2016
Getting Lua
• lua.org > download
• OS package manager • apt-get install lua • brew install lua
LuaRocks
• luarocks.org > install
• OS package manager • apt-get install luarocks
@etiene_dHackference 2016
Key Concepts
@etiene_dHackference 2016
• The only way to structure data
• Array, dictionary, object, list, queue, module…
• Any value can be a key, except nil and nan
• Behind the scenes: array or hash table
• Passed as reference
• The length operator: #
• pairs(t) x ipairs(t)
Tables Tables Tables
@etiene_dHackference 2016
Tables
Header
key value
“x” 9.2
nil
value
100
200
300
nil
@etiene_dHackference 2016
• The only way to structure data
• Array, dictionary, object, list, queue, module…
• Any value can be a key, except nil
• Behind the scenes: array or hash table
• Passed as reference
• The length operator: #
• pairs(t) x ipairs(t)
Tables
@etiene_dHackference 2016
Tables
local a = { 1, 3, 5, 7, 9}
local sum = 0
for i=1,#a do
sum = sum + a[i]
end
print(sum) -- 25
@etiene_dHackference 2016
local a = { 1, 3, 5, 7, 9}
local sum = 0
for i=1,#a do
sum = sum + a[i]
end
print(sum) -- 25
Tables
local a = {}
a[1] = 1
a[2] = 3 -- etc
local sum = 0
for _, x in ipairs(a) do
sum = sum + x
end
print(sum)
@etiene_dHackference 2016
local a = { 1, 3, 5, 7, 9}
local sum = 0
for i=1,#a do
sum = sum + a[i]
end
print(sum) -- 25
local point = { x = 10, y = 25}
print(point[“x”], point[“y”]) -- 10 25
print(point.x, point.y) -- 10 25
print(point[x], point[y]) -- nil nil (attention!)
Tables
@etiene_dHackference 2016
local a = { 1, 3, 5, 7, 9}
local sum = 0
for i=1,#a do
sum = sum + a[i]
end
print(sum) -- 25
local point = { x = 10, y = 25}
print(point[“x”], point[“y”]) -- 10 25
print(point.x, point.y) -- 10 25
print(point[x], point[y]) -- nil nil (attention!)
-- sets and multisets
local ips = {[“5.101.112.0”] = true, [“213.35.128.0”] = true}
local conns = {[“5.101.112.0”] = 5, [“213.35.128.0”] = 2}
Tables
@etiene_dHackference 2016
-- Cipher module
--[[ Based on algorithms/caesar_cipher.lua
by Roland Yonaba ]]
local cipher = {}
local function ascii_base(s)
return s:lower() == s and ('a'):byte() or ('A'):byte()
end
function cipher.caesar( str, key )
return str:gsub('%a', function(s)
local base = ascii_base(s)
return string.char(((s:byte() - base + key) % 26) + base)
end)
end
return cipher
Modules
@etiene_dHackference 2016
-- Cipher module
--[[ Based on algorithms/caesar_cipher.lua
by Roland Yonaba ]]
local cipher = {}
local function ascii_base(s)
return s:lower() == s and ('a'):byte() or ('A'):byte()
end
function cipher.caesar( str, key )
return str:gsub('%a', function(s)
local base = ascii_base(s)
return string.char(((s:byte() - base + key) % 26) + base)
end)
end
return cipher
Modules
@etiene_dHackference 2016
-- Cipher module
--[[ Based on algorithms/caesar_cipher.lua
by Roland Yonaba ]]
local cipher = {}
local function ascii_base(s)
return s:lower() == s and ('a'):byte() or ('A'):byte()
end
function cipher.caesar( str, key ) --cipher.caesar = function(str,key)
return str:gsub('%a', function(s) --cipher["caesar"] = function(str,key)
local base = ascii_base(s)
return string.char(((s:byte() - base + key) % 26) + base)
end)
end
return cipher
Modulespublic
@etiene_dHackference 2016
-- Cipher module
--[[ Based on algorithms/caesar_cipher.lua
by Roland Yonaba ]]
local cipher = {}
local function ascii_base(s)
return s:lower() == s and ('a'):byte() or ('A'):byte()
end
function cipher.caesar( str, key )
return str:gsub('%a', function(s)
local base = ascii_base(s)
return string.char(((s:byte() - base + key) % 26) + base)
end)
end
return cipher
Modules
private
@etiene_dHackference 2016
-- Cipher module
--[[ Based on algorithms/caesar_cipher.lua
by Roland Yonaba ]]
local cipher = {}
local function ascii_base(s)
return s:lower() == s and ('a'):byte() or ('A'):byte()
end
function cipher.caesar( str, key )
return str:gsub('%a', function(s)
local base = ascii_base(s)
return string.char(((s:byte() - base + key) % 26) + base)
end)
end
return cipher
Modules
local c = require “cipher”
print(c.caesar(“test”,3) -- whvw
@etiene_dHackference 2016
• Overload operators
• Override built-in functions such as tostring
• Treat missing fields or intercept new field creation
• Call table as a function
• Metamethods:__add, __sub, __mul, __div, __mod, __pow, __unm, __concat, __len, __eq, __lt, __le, __index, __newindex, __call, __tostring, __ipairs, __pairs, __gc
Metatables
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos
Complex numbers
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos
Complex numbers
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos
Complex numbers
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos
Complex numbers
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos
Complex numbers
@etiene_dHackference 2016
local mt = {}
local function new(r, i)
return setmetatable({ real = r or 0, im = i or 0}, mt)
end
local function is_complex(v)
return getmetatable(v) == mt
end
local function add(c1, c2)
if not is_complex(c1) then
return new(c2.real + c1, c2.im)
elseif not is_complex(c2) then
return new(c1.real + c2, c1.im)
end
return new(c1.real + c2.real, c1.im + c2.im)
end
local function tos(c)
return tostring(c.real) .. "+".. tostring(c.im) .. "i"
end
mt.__add = add
mt.__tostring = tos>local c1 = new(2,3) >print( c1 + 5 ) 7+3i
Complex numbers
@etiene_dHackference 2016
local square = { x = 10, y = 20, side = 25 }
function square.move(obj, dx, dy)
obj.x = obj.x + dx
obj.y = obj.y + dy
end
function square:area()
return self.side ^ 2
end
print(square:area()) -- 625
Objects
@etiene_dHackference 2016
local square = { x = 10, y = 20, side = 25 }
function square.move(obj, dx, dy)
obj.x = obj.x + dx
obj.y = obj.y + dy
end
function square:area()
return self.side ^ 2
end
print(square:area()) -- 625
Objects
@etiene_dHackference 2016
local square = { x = 10, y = 20, side = 25 }
function square.move(obj, dx, dy)
obj.x = obj.x + dx
obj.y = obj.y + dy
end
function square:area()
return self.side ^ 2
end
print(square:area()) -- 625
Objects
@etiene_dHackference 2016
local square = { x = 10, y = 20, side = 25 }
function square.move(obj, dx, dy)
obj.x = obj.x + dx
obj.y = obj.y + dy
end
function square:area()
return self.side ^ 2
end
print(square:area()) -- 625
Objects
@etiene_dHackference 2016
local square = { x = 10, y = 20, side = 25 }
function square.move(obj, dx, dy)
obj.x = obj.x + dx
obj.y = obj.y + dy
end
function square:area()
return self.side ^ 2
end
print(square:area()) -- 625
local square2 = (x = 30, y = 5, side = 10}
print(square.area(square2)) -- 100
Objects
@etiene_dHackference 2016
local Square = {}
function Square:new(x, y, side)
local o = { x = x, y = y, side = side}
setmetatable(o, self)
self.__index = self
return o
end
function Square:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Square:area()
return self.side ^ 2
end
return Square
Object Orientation
@etiene_dHackference 2016
local Square = {}
function Square:new(x, y, side)
local o = { x = x, y = y, side = side}
setmetatable(o, self)
self.__index = self
return o
end
function Square:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Square:area()
return self.side ^ 2
end
return Square
Object Orientation
@etiene_dHackference 2016
local Square = {}
function Square:new(x, y, side)
local o = { x = x, y = y, side = side}
setmetatable(o, self)
self.__index = self
return o
end
function Square:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Square:area()
return self.side ^ 2
end
return Square
Object Orientation
@etiene_dHackference 2016
local Square = {}
function Square:new(x, y, side)
local o = { x = x, y = y, side = side}
setmetatable(o, self)
self.__index = self
return o
end
function Square:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Square:area()
return self.side ^ 2
end
return Square
Object Orientation
@etiene_dHackference 2016
local Square = {}
function Square:new(x, y, side)
local o = { x = x, y = y, side = side}
setmetatable(o, self)
self.__index = self
return o
end
function Square:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Square:area()
return self.side ^ 2
end
return Square
local Square = require “square”
local s1 = Square:new(10,20,25)
local s2 = Square:new(30,5,10)
print(s1:area()) -- 625
print(s2:area()) -- 100
Object Orientation
Thank you!
etiene.net github.com/Etiene/
@etiene_d
@etiene_dHackference 2016
Going further
@etiene_dHackference 2016
• Hardware • eLua: http://www.eluaproject.net/ • nodemcu: http://nodemcu.com
• Scientific Computing and Machine Learning • SciLua http://www.scilua.org/ • Torch: http://torch.ch • GSL Shell: http://www.nongnu.org/gsl-shell/
Cool tools in Lua
@etiene_dHackference 2016
• Game development • Love2D: https://love2d.org/ • Defold: http://www.defold.com/ • Cocos2d: http://www.cocos2d-x.org/ • Corona: https://coronalabs.com
• Web development • (Nginx) OpenResty http://openresty.org • Luvit: https://luvit.io/ • Lapis: http://leafo.net/lapis/ • Sailor: http://sailorproject.org/ • Starlight: http://starlight.paulcuth.me.uk/
Cool tools in Lua
@etiene_dHackference 2016
• IDE • ZeroBrane Studio: http://studio.zerobrane.com/
• Testing • Busted: http://olivinelabs.com/busted/
• Package management • LuaRocks http://luarocks.org
• Misc • Moonscript: http://moonscript.org/ • Awesome Lua:
https://github.com/LewisJEllis/awesome-lua
Cool tools in Lua
@etiene_dHackference 2016
• Community • Lua mail list: http://www.lua.org/lua-l.html • #LuaLang on Twitter • Lua community blog: http://lua.space • Lua’s subreddit: http://reddit.com/r/lua • Lua’s IRC channel: irc.freenode.net #lua
• Books • Programming in Lua: http://www.lua.org/pil/ • Lua Programming Gems: http://www.lua.org/gems/
• Misc • CodeCombat: https://codecombat.com
Resources
Thank you!
etiene.net github.com/Etiene/
@etiene_d