This lesson is a bit "academic" so prepare a cup of tea or coffee to go through it calmly and attentively :)
We have already vague understanding that there could be numbers
and strings
, they could be assigned to variables
and also added, subtracted, multiplied etc. It's time to quickly "formalize" this knowledge.
You remember we agreed to call statements small pieces of code which instruct machine to execute some action.
Now expressions are smaller pieces, often parts of statements, which express or calculate some value. Regard an example:
print(3+5*4)
the whole line is a statement, which prints the result of expression 3+5*4
. But what if we print a simple
string in quotes (i.e. text constant, or "literal"):
print('hafanana')
in this case 'hafanana'
is an expression anyway. In more general terms expression consists of values joined by
operators. Values could be represented by variables or constants.
Operators are all those +
, -
, and so on. We'll get more details in a few minutes. But now let's talk about types.
Let's regard constant expressions more closely. We already found they could be like text or like numbers. Sometimes we found they do not always suit each other. For example:
print(10 * 'xo')
this throws an error like attempt to mul 'number' with 'string'. So strings seemingly couldn't be multiplied.
Now we understand any value has some type - and by the way this could be detected using type(...)
function:
print(type(10))
print(type('blaha'))
These print number
and string
respectively. But the language has more than just two types. Try this line:
print(10 == 8, 10 == 10, type(10 == 5))
You'll see three results false
, true
and boolean
. So all these "comparison operators" like equality return
special type boolean
, which has only two values - these "true" and "false" (you can use them in your program literally).
The value of boolean type is usually expected inside if ... then
or while ... do
constructs.
Operations on numbers
We already understand there are +
, -
, *
and /
, as in kid's school. There are few more handy operations - try
these lines:
print(8 / 3) -- general division
print(8 // 3) -- integer division
You'll see 2.666...67
and simple 2
. The second version of division throws away any fractional part.
print(100 % 3) -- remainder
print(3^4) -- raising to power
Operations on strings
By now we know only one string operation - concatenation, and that's enough. Other string manipulations are done with special functions instead, we'll learn of them later.
print('10' .. '10')
Note that integer values are treated as text because they are surrounded with quotes and string concatenation operator
is applied to them. Hence the result 1010
(rather than 20
).
Comparison operators
These are interesting. They use as operands other types, like numbers or strings, and their result is boolean (true or false):
print('bla' == 'mla') -- is the first equal to second?
print(5 > 3) -- is greater than?
print(5 >= 2+3) -- is greater or equal?
print(2^3 < 10) -- is less than?
print(100%9 <= 1) -- is less or equal?
print(100 // 10 ~= 10) -- is not equal
Boolean operators
Sometimes we need to check more than one condition, like we want to know if user entered yes
or ja
(perhaps, user
is German?). In other case we want to know if user is no less than 18
and no more than 100
years. These are achieved
with operations or
, and
respectively:
print('enter "yes" or "ja":')
response = io.read('*l')
print(response == 'yes' or response == 'ja')
print('enter your age:')
age = io.read('*n')
print(age >= 18 and age <= 100)
There is also handy operation not
, which inverts logical value following it. Just be careful with it, see below.
As Lua
language wants to be user-friendly, it allows in some cases to automatically convert values of different
types to match those wanted by operators. For example:
print(10 + 'SO') -- error
print(10 + '50') -- gives 60
so if we try numeric addition on a string, which could be converted to number, it works all right!
For exercise try some other cases to see when auto-conversion works. Explain the results:
print('5' * '5')
print(10 + '-3e1')
print('five is ' .. 5)
print('true is ' .. true)
print(10 == '10')
print(not 10 == 8)
print(not (10 == 8))
The last two lines could be confusing. Obviously not 10
is executed first (and what is result?) and then only
compared to 8
. Thus the parentheses are necessary for proper calculation order.
Double not
would simply convert value to logical, retaining its "logical meaning" so to say. Play a bit more with it to see how different values are converted:
print(not not true)
print(not not false)
print(not not 10)
print(not not '10')
print(not not 0)
print(not not '0')
print(not not nil)
You should find that only one of non-boolean values is treated like false
.