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!
Important! We now use slightly amended syntax for LUA! As colleagues complained about the lack of compound operator and unusual non-equal operator, we implemented these small additions (source here) and use both in the JS-sandbox mentioned above - and in the on-site sandbox (used by "Run" button and problem checker). This should be fully compatible. More details at the end of this page.
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.5.0 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.5 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
Our version of Lua is slightly amended to make it more familiar for users with Python/C/Java/PHP experience:
"Not equals" operator could be spelled as != in addition to standard ~=, and also unary ! could be used as logical not.
Compount assignments added (e.g. +=, -=, *= and so on, including ..= for concatenating assignment)
Reserved word function could be shortened to fn to help declaring lambdas etc.
Type-hint comments could be used as short identifiers following the arguments of a function, or the function header itself, separated with
: - they are not checked (i.e. serve exactly as a comment of special form).