Logical Operators

Boolean Values

In order to provide a baseline for the examples below, let's start with a quick look at the boolean values of true and false:

print(true) -- true
print(false) -- false

As we discussed earlier, when a non-boolean value is evaluated in a boolean context that value is coerced to its boolean equivalent. It is common to refer to values that are coerced to true as being truthy, while those that are coerced to false are falsy.


The first and most simple Boolean operator is the not operator, which simply inverts the truthiness of the value it operates on and returns a boolean value:

print(not true) -- false
print(not false) -- true

print(not nil) -- true

-- careful!
print(not 0) -- false
print(not "") -- false
print(not {}) -- false

We included a few examples of type coercion to show how it works. If you are familiar with boolean coercion in other programming languages, be careful when evaluating 0, "", and {}, as they may provide unexpected results.


The next operator is the and operator, which evaluates to truthy when both inputs are truthy, and otherwise evaluates to falsy:

print(true and true) -- true
print(true and false) -- false
print(false and true) -- false
print(false and false) -- false

The previous examples shows that the and operator evaluates boolean values in the expected way. The following examples demonstrate how it evaluates non-boolean values:

print(false and nil) -- false
print(true and nil) -- nil
print(true and 0 and nil) -- nil
print(true and nil and 0) -- nil

Note that the and operator returns either the first non-truthy value, or the last truthy value if all values are truthy. This behavior allows the and operator to both provide logical operators and provide a simple control structure.


Complementary to the and operator is the or operator, which evaluates to truthy if either of the inputs are truthy, and evaluates to falsy otherwise.

print(true or true) -- true
print(true or false) -- true
print(false or true) -- true
print(false or false) -- false

As with the and operator, the or operator performs logical operations as expected, and also operates on non-boolean values:

print(nil or false) -- false
print(nil or true) -- true
print(nil or 0 or true) -- 0
print(0 or nil or true) -- 0

The or operator returns either the first truthy value it encounters, or the last falsy value if all values are falsy. Like the and operator, this allows the or operator to both provide logical operators and provide a simple control structure that is often very convenient.


Boolean operators can be chained together to create "compound" operations:

print(true and not true) -- false
print(true or not true) -- true

How this works will become clean in the next section, where we discuss precedence.