The Lua programming language has similarities to Python syntax, though being much simpler, compact and having less features. This brief intro should help you to start with it immediately (even if you are not Python programmer).
At the same time it is industrial-grade language - you may look at projects Tarantool
(difficult to explain what
it is but it is cool solution for big enterprises) or Love2D
- portable game engine for example.
You can play with it interactively using sandboxes linked below. Here is the main Lua documentation collection - I recommend "Programming in Lua" book and "Reference Manual" for details on functions etc.
Lua Sandbox #1 (compiled to JS) and Lua Sandbox #2 (based on Linux)
Also Lua
button is available for execution code from the "solution" box on any task view page. Note that it
supports standard Lua 5.4
and LuaJIT 2.1
which is about ten times faster (see below).
To install Lua on your computer visit official Lua download page.
PyCharm
user may follow this advice from Mathias: after downloading
and installing Lua, then install the EmmyLua
plugin in PyCharm
- that allows you to develop and run
Lua programs directly within PyCharm!
These are quite similar to Python:
Lua:
x = 5
word = 'Wonder!'
print(word, x)
You'll see however that print
makes significant tabulations between elements. Alternative is
io.write(word, x)
it makes no tabulations or spaces between elements, and doesn't append newline (and also returns file value which may confuse in interactive mode).
Another alternative is to concatenate elements to single string (use ..
operator):
print(word .. x)
In the example above we've seen that no type conversion is needed when concatenating string to integer. Lua is quite "weak-typed" and converts values back and forth when needed. Look at the following example:
print('100' + 5) -- gives '105.0'
print('100' .. 5) -- gives '1005'
You see, with arithmetic addition operator both values are converted to numbers. With concatenation (string addition) operator they both are converted to strings.
Numbers are either integer
or float
, the latter showing distinctive fractional part (even if it is .0
).
There are also string
values and boolean
values (true
, false
). If value is not initialized it is nil
.
Arithmetic operators are +
, -
, *
, /
and also //
(integer division) along with %
(modulo). There are
no short forms like a += 1
or a++
for incrementing valriable.
The only complex type is table
, which works at the same time as linear array (list) and dictionary (key-value
storage). Slightly unusual feature is indexes normally start with 1
rather than 0
(though one can use 0
anyway):
a = {3, 5, 7} -- initializing with curly braces
print(a[2]) -- prints 5
a[4] = 11 -- set another value
print(#a) -- prints 4, since '#' prefix gets length of array-like table
table.insert(13) -- slightly clumsy way of appending to array-like table
print(table.concat(a, ':')) -- prints 3:5:7:11:13
Using tables with non-numeric indexes (keys) works like dealing with dictionary in Python:
a = {john = 15}
print(a['john'], a['jack']) -- prints "john nil"
a['jane'] = 18
a['zlobodan'] = {} -- empty table inserted as table element
Conditionals if-else
and while
loops are quite similar to Python, just the internal block is not
defined with indentation - rather simply is framed with do .. end
words (or then/else .. end
):
x = 1
while x < 100 do
if x % 5 == 0 then
print('fizz')
elseif x % 3 == 0 then
print('buzz')
end
x = x + 1
end
There is break
statement, but no continue
(instead it is possible to use goto
).
There are two versions of for
loop, the first of them numeric, the other for tables etc:
for i = 1, 10 do
print(i .. ' squared is ' .. (i * i))
end
for i = 1, 30, 2 do -- step is 2 instead of 1
print('odd value', i)
end
a = {2, 3, 5, 7, 11}
for k, v in ipairs(a) do -- "ipairs" iterates over numeric indexes
print(k, v)
end
b = {john=15, jake=18, jill = 13} -- and "pairs" for non-numeric
for k, v in pairs(b) do
print(k, v)
end
Quite similar to Python - just define function and use it:
function sqr(x)
return x * x
end
print(sqr(5)) -- prints 25
Using several values in assignments and returns is allowed (tuple-like behavior)
function intdiv(x, y)
return x // y, x % y
end
q, r = intdiv(100, 7)
If you use local variables inside function (the same inside if
, while
etc blocks) it makes sense to mark
them with local
word, otherwise they are global:
function haha(x)
t = x * (x + 1) // 2
local s = x * x
return t, s
end
haha(15) -- we ignore returned values for this example
print(t, s) -- prints "120 nil"
There is a typical small set of useful functions in the standard library, most of them are assigned as
values to dedicated tables with names like math
, string
, io
:
print(math.sqrt(3*3 + 4*4)) -- square root
print(string.upper('Clown')) -- prints CLOWN
Refer to reference manual for full list of such "methods". Alternatively it is easy to print out their names, since they are defined via table, e.g.:
for name, func in pairs(math) do
print(name)
end
There is also behavior allowing to use tables as classes / objects in Python, we won't go into details here,
but it is used to shorten popular operations, for example with string
:
word = 'abracadabra'
print(string.sub(word, 2, 5)) -- prints substring of "word" from 2 to 5, i.e. "brac"
print(word:sub(2, 5), word:len()) -- does the same, additionally prints length of "word"
The Lua
language comes in several implementations. On this site you can run at least two of them.
Standard "scripting" implementation, corresponding to Lua 5.4.6
is executed by default. However
if you add any comment with word "luajit" in the first line of your code, LuaJIT 2.1
implementation is
used. It is significantly faster (about 10
times), but conforms to language version 5.1
with some
features included from 5.2
and 5.3
versions. E.g.
print(_VERSION) -- prints 5.4 normally
but if you add a comment in the first line
--luajit
print(_VERSION) -- prints 5.1, as it is executed by LuaJIT
Try this small program (summing up square roots for values up to million) with both versions and you'll see the difference:
res = 0
for i=1,1000000 do
res = res + math.sqrt(i)
end
print(res, os.clock()) -- prints time in seconds from the execution start