Lua is a dynamically-typed language, meaning that there are no type definitions, and no need to declare the types of variables. Instead, the type is inferred from the value.
This can be an advantage or a disadvantage depending upon the context, but it is part of what allows Lua to have such a simple grammar.
Lua defines a handful of types, which we will look at next:
Numbers
The first data type we will look at is number. Numbers are used to represent quantities or amounts, and are also used in some control structures and to retrieve values from tables.
Whereas many languages differentiate between integer and floating point numbers, Lua treats all numbers as double-precision floating-point numbers.
Lua is quite flexible about how numbers are formatted, accepts most common floating-point formats, and will even automatically convert strings to numbers when performing arithmetic operations:
-- integer
print(123) -- 123
-- floating point
print(1.23) -- 1.23
print(0.0456) -- 0.0456
-- exponential
print(0.123e+3) -- 123
print(123e-3) -- 0.123
print(4.56E2) -- 456
-- hexadecimal
print(0x00) -- 0
print(0x7B) -- 123
print(0xff) -- 255
--strings
print("120" + 3) -- 123
print("0x78" + 3) -- 123
We will go deeper into working with numbers in the arithmetic operations section.
nil
Whereas most types convey a value, many programming languages include a type that specifies that
there is no value. This concept varies slightly between languages, but is conveyed by None
in
python and NULL
in
C and
SQL, in Lua this value is nil.
We saw earlier that when a variable is defined without a value it is assigned the value of nil, which provides a good example of what nil is - it represents the condition when there is no value.
This might sound a bit abstract, this is one of those topics that is difficult to comprehend by simply reading about it, but will become clear after "seeing it in action" in the coming sections.
Booleans
Boolean values represent the logical values of
true
and false
. Some languages represent these values as the
integers 1
and 0
, respectively, while others represent them
with the words True
and False
. In Lua, these values are represented by (the lowercase) true
and false
.
Truthiness & Falsiness
In addition to the strictly boolean values, Lua also supports coercing non-boolean values into their boolean equivalents so that they can be used in boolean contexts.
This is such a common occurrence that it often makes sense to refer to non-boolean values as their
boolean-equivalents; values that are coerced to true
are considered truthy, while those that
are coerced to false
are regarded as falsy.
Value coercion in Lua is simple: Lua regards nil
to be falsy, and all other values are truthy.
This can lead to some surprising results result for those that are familiar with coercion in other
languages, where 0
, empty strings ""
, and empty collections {}
are usually regarded as being
falsy.
Strings
The next type we will look at is the string. We have an entire chapter dedicated to strings, but as a brief introduction strings are arrays of bytes, where each byte or group of bytes represents character, which are grouped together to form words or other text-based sequences.
Lua strings are immutable, meaning that they cannot be modified after they are created. Changing a string requires creating a new string that consists of the characters of the previous string, plus whatever changes are desired. We will learn more about this when we look at string buffers and format strings.
Lua strings are defined by sequences of characters contained within any of:
- Double quotes
- Single quotes
- Double square brackets
The characters of strings defined with either single or double quotes must exist on a single line, while those in strings defined with brackets can be on multiple lines. Strings defined with single and double quotes are equivalent, and both types of quotes are supported so that quote characters can be included in strings themselves.
Tables
Lua implements a single data structure type, which is implemented as a general-purpose collection that encompasses functionality that is usually implemented by several different data structures in other programming languages. This makes tables powerful, but can also make it a bit challenging to work with, and can lead to surprising results if one is not careful. For example, while tables can act as both lists and mappings, most table functions generally make an assumption about how the table is being used. When a table function is used in the wrong context it won't generate an error, it will just return an unexpected result.
Tables play an important role in Lua, and we will learn much more about them in the Tables chapter.
Functions
Like most programming languages, Lua supports the ability to add new functionality by implementing functions. At a high-level, functions are "callable units" of code that can accept 0 or more parameters, perform some operations, then return 0 or more results. We will look at functions in more detail in the Functions chapter.
Userdata
Userdata is a type in Lua that basically represents a "black box" of data that is used in the code, but can't be printed or otherwise inspected. Using userdata is an advanced topic that generally involves integrating C code with Lua. In most cases anyone other than advanced users who are integrating Lua and C will only see userdata when debugging a script and printing values, and the only reason we bring it up is so that reader have some idea what they are looking at when they see it.