unknown_document

We couldn't find that page... Were you looking for one of these?


Lua's Relational Operators
Relational Lua's relational operators are more or less the same as in most other languages: local x = 2 local y = 3 print ( x > y ) -- false print ( x < y ) -- true print ( x >= y ) -- false print ( x <= y ) -- true print ( x <= x ) -- true print ( x >= x ) -- true The relational operators allow one to determine when values are greater-than or less-than others, and include a variant that also allows the variables to be equal. Equality Lua's equality operator uses two equal signs == , which is differentiated from the variable assignment operator = which uses a single equal sign: local x = 2 local y = 3 print ( x == y ) -- false print ( x == x ) -- true This operator returns true when the two values are equal, otherwise it returns false . Inequality Like equality , it can often be useful to know when two values are not equal. Lua implements this using the ~= operator: local x = 2 local y = 3 print ( x ~= y ) -- true print ( x ~= x ) -- false This operator returns false when the two values are equal, otherwise it returns true .
Lua's Logic 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 . not 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. and 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 . or 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. Compound 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 .
Lua's Concatenation Operator
Concatenation refers to the common operation of joining of two strings . In Lua, when two strings are concatenated the result is a third string that contains the characters of the first string followed by the characters contained in the second string: local x = "left side" local y = "right side" print ( x .. y ) -- left sideright side -- separating strings with a literal " " print ( x .. " " .. y ) -- left side right side Note that the concatenation is literal: no space is added between two concatenated strings. When concatenating sentences be sure to include a literal space between the two strings. Concatenation also works with numbers , by first coercing each value to its string-equivalent then concatenating those values: local x = 2 local y = 3 print ( x .. y ) -- 23 Note that concatenation won't work with other value fundamentals, such as booleans or nil .
Lua's Arithmetic Operators
Basics Let's first take a look at the basics, addition , subtraction , multiplication , and division . These work as one would expect: local x = 2 local y = 3 print ( x + y ) -- 5 print ( x - y ) -- -1 print ( x * y ) -- 6 print ( x / y ) -- 0.66666666666667 Negation Whereas almost all languages allow a value to be negated by multiplying it by -1 to negative it, Lua additionally allows a value to be negated by simply prefixing it with - . local x = 2 local y = 3 print ( - x ) -- -2 print ( - y ) -- -3 print ( x + - y ) -- -1 Note that negation occurs independently of other operators, as shown in the last case. We will learn more about this in a moment when we discuss precedence . Exponentiation Lua supports exponentiation with the ^ operator: local x = 2 local y = 3 print ( x ^ y ) -- 8.0 print ( y ^ - x ) -- 0.11111111111111 Modulus Like many programming languages modular arithmetic in Lua uses the % operator. While the topic of modular arithmetic is well outside the scope of learning about Lua, this is a useful but often misunderstood function, so let's give it a quick review. To calculate a % b, one first finds the largest integer k such that multiplying k by b is less than a , then the result is the difference or remainder, a - kb . local x = 2 local y = 3 print ( x % y ) -- 2 print ( y % x ) -- 1 In the first example y is greater than x , so the remainder is simply x . In the second example the largest integer k is 1 , so that the remainder is 3-2=1 . Bitwise Lua also supports the basic bitwise operations. While bitwise operations are very important in computing, they are used in a fairly narrow range of applications so we won't spend too much time on them other than to show which operations are supported and a simple example of how they work: local x = 2 local y = 3 print ( x & y ) -- 2 print ( x | y ) -- 3 print ( x ~ y ) -- 1 You can learn more about bitwise operations here .
Lua's Length Operator
Lua includes a length operator # which (in theory) returns the number of items contained in the value to which it is applied. However, it is frankly a bit wonky and can give unexpected results if used outside of a fairly narrow range of applications. Part of the wonkiness is that it behaves differently depending on the type it is acting upon. For this reason, we look at how it behavior with each of the following types: List-like Tables Map-like Tables Set-like Tables Strings
Operator Precedence in Lua
As we all learned in algebra, it is not only important to understand how operators work, but also understand the order in which operators are applied. The order in which operators are applied is governed by their precedence and their association . Lua operators have the following precedence, ordered from highest to lowest priority, and association: Group Operators Association Exponentiation ^ Right Unary Operators not # - ~ Left Arithmetic * / % Left Arithmetic + - Left Concatenation .. Right Bitwise & Left Bitwise ~ Left Bitwise | Left Relational < > <= >= ~= == Left Logical and Left Logical or Left As with algebra, parentheses can be used to override the order of precedence of an expression.
Lua
Lua is a lightweight, cross-platform, high-level programming language that has become increasingly-popular as an embedded scripting language. Lua is often praised as a clean, simple, easy to learn scripting language that is applicable to a wide range of tasks. Today Lua can be found in a wide range of applications ranging from wezterm to xplr and neovim . Let's get started.
Creating Lua Maps
Maps , often also called Dictionaries and associative arrays , are data structures that organize elements such that each element can be easily retrieved by its name, or key. Unlike lists maps do not guarantee fixed ordering, values can be assigned to maps in any order, and retrieved in any order. A map is created by instantiating a table of values, as below: -- initialize a mapping of key, value pairs local x = { a = 1 , b = 2 , c = 3 , d = 4 , } Let's try printing the map : print ( x ) -- table: 0x59b68bdd9de0 As we saw in lists , when Lua prints a table it displays the type (table) followed by its address in memory, which can be useful in some situations but generally isn't what we want. Inspecting the values of a map requires accessing them individually. -- access values stored in the table print ( x [ "a" ]) -- 1 print ( x [ "b" ]) -- 2 print ( x [ "c" ]) -- 3 print ( x [ "d" ]) -- 4 -- accessing values *not* in the table returns nil print ( x [ "x" ]) -- nil Lua also allows map values to be accessed by referencing map keys as properties: -- access values stored in the table print ( x . a ) -- 1 print ( x . b ) -- 2 print ( x . c ) -- 3 print ( x . d ) -- 4 -- accessing values *not* in the table returns nil print ( x . x ) -- nil There is a second method for creating maps , which is often helpful when creating maps programmatically such as in a loop . In this this method, an empty map is created and assigned to a variable , then values are assigned directly to each key: -- initialize an empty table local x = {} -- assign values to each key x [ "a" ] = 1 x [ "b" ] = 2 x [ "c" ] = 3 x [ "d" ] = 4 After the map is created, its elements can be accessed as usual: -- access values stored in the table print ( x [ "a" ]) -- 1 print ( x [ "b" ]) -- 2 print ( x . c ) -- 3 print ( x . d ) -- 4
Repetition in Lua Patterns
The next step to understanding patterns is repetition , which specify not only the class of the character, but how sequences of those characters should be matched. Repetition specifications are indicated by placing one of the following characters immediately after a character class Specifier Description Greedy Default matches any single character in the class * matches a sequence consisting of 0 or more characters in the class Yes - matches a sequence consisting of 0 or more characters in the class No + matches a sequence consisting of 1 or more characters in the class Yes ? matches 0 or 1 character in the class Greedy refers to how variable counts treat a matching sequence of characters. "Greedy" matching indicates that the pattern will always match the longest possible sequence, while "non-greedy" matching indicates that the pattern always match the shortest possible sequence. Let's look at each of these to get a better idea of how this works. First, let's look at the default behavior, when no repetition is specified: local pattern = "%d" print ( string.match ( "abc" , pattern )) -- nil print ( string.match ( "1abc" , pattern )) -- 1 print ( string.match ( "12abc" , pattern )) -- 1 print ( string.match ( "123abc" , pattern )) -- 1 When no repetition specifications are defined, by default a character class matches a single character. In the first example no match was made because there are no digits in the target, and therefore the call to match returned nil , while the pattern was able to match a single character of the other targets. Next, let's look at * which greedily matches 0 or more characters from the character class : local pattern = "%d*" print ( string.match ( "abc" , pattern )) -- print ( string.match ( "1abc" , pattern )) -- 1 print ( string.match ( "12abc" , pattern )) -- 12 print ( string.match ( "123abc" , pattern )) -- 123 Notice that although there are no digits in the first target, the pattern still matched (it did not return nil ). Instead, it matched an empty string. This is due to the repetition specification which allows the pattern to match 0 characters. For each of the other targets, this pattern matched all available digits. Now let's compare that behavior to that of a non-greedy match: local pattern = "%d-" print ( string.match ( "abc" , pattern )) -- print ( string.match ( "1abc" , pattern )) -- print ( string.match ( "12abc" , pattern )) -- print ( string.match ( "123abc" , pattern )) -- What is interesting in the case is that the pattern matched, but returned just an empty string. It is difficult to see this behavior with such a simple pattern, so let's repeat with a slightly more complicated pattern: local pattern = "%d-%a" print ( string.match ( "abc" , pattern )) -- a print ( string.match ( "1abc" , pattern )) -- 1a print ( string.match ( "12abc" , pattern )) -- 12a print ( string.match ( "123abc" , pattern )) -- 123a In this case, the pattern matched the fewest number of digits required to additionally match a single letter. In order to match the letter, the pattern had to match all numbers leading up to it. Another variation on the * specifier is the + specifier, which greedily-matches at least 1 character from the character class : local pattern = "%d+" print ( string.match ( "abc" , pattern )) -- nil print ( string.match ( "1abc" , pattern )) -- 1 print ( string.match ( "12abc" , pattern )) -- 12 print ( string.match ( "123abc" , pattern )) -- 123 The main difference is shown in the top line, where * matches an empty string, while + simply won't match. Finally, the ? specifier matches 0 or 1 repetitions of the character_classes : local pattern = "%d?" print ( string.match ( "abc" , pattern )) -- print ( string.match ( "1abc" , pattern )) -- 1 print ( string.match ( "12abc" , pattern )) -- 1 print ( string.match ( "123abc" , pattern )) -- 1 Now that we have the tools we need to understand and create patterns, let's move on to the next topic, captures .
Creating Lists in Lua
Lists , often also called arrays , are data structures that organize elements such as values by index. A list is created by instantiating a table of values, as below: -- initialize a table with values local x = { "a" , "b" , "c" } Let's try printing the list : print ( x ) -- table: 0x6121ee19eda0 By default, when Lua prints a table it displays the type (table) followed by its address in memory, which can be useful in some situations but generally isn't what we want. Inspecting the values of a list requires accessing them individually. -- access values stored in the table print ( x [ 1 ]) -- a print ( x [ 2 ]) -- b print ( x [ 3 ]) -- c -- accessing values *not* in the table returns nil print ( x [ 9 ]) -- nil There is a second method for creating lists , which is often helpful when creating lists programmatically such as in a loop . In this this method, an empty list is created and assigned to a variable , then values are assigned directly by index: -- initialize an empty table local x = {} -- assign values by index x [ 1 ] = "d" x [ 2 ] = "e" x [ 3 ] = "f" After the list is created, its elements can be accessed as usual: -- access values stored in the table print ( x [ 1 ]) -- d print ( x [ 2 ]) -- e print ( x [ 3 ]) -- f A variation on this method uses the table.insert method to append values to the list , and will be discussed shortly .