Lua

## Copying modules to another wiki

Modules hosted on the developer fandom wiki can be used on other wikis, but requires some steps:

1. Copy-paste the module to your wiki.
2. Search sections that contain text like `require("text")`. Replace all mentions of `require("dev:")` with `require("module:")`

## Basics

* **Signifier** (CSS) or **identifier**: a sequence of characters in the code that identifies a variable, function, or property. ... An identifier differs from a string in that a string is data, while an identifier is part of the code.
	+ usually case-sensitive.
	+ Some words are reserved, meaning they cannot be used as an identifier.
* **Comments** is a way to add an inline comment to the code, without affecting it. When the program is run, it will ignore comments.
	+ CSS uses `/\*\* \*\*/`
	+ HTML uses `<!-- -->`
	+ Lua uses `--` at the start of a line or `----` to contain the comment across line breaks.
* A **chunk** is a single collection of statements or functions.
	+ A chunk can be written on a single line, but that tends to get kind of messy. Therefore many prefer to use line break to place each statement seperately on its own line. For instance, both of the codes in the table below will work the same way:

```
if (age < 14) or (age > 67) then io.write("You shouldn't work\n") end
```
```
if (age < 14) or (age > 67)
then io.write("You shouldn't work\n")
end
```

* Statements: `if` `then` `else` `ifelse` `for`
	+ Any variable you define inside a statement or function, are called **local variables**. This means that this variable is local to this statement chunk, and the value that's set here cannot be found outside of this chunk. Example: `local localVar = 10`
	+ A **relational operator** tests or defines some kind of relation between two entities. These include numerical equality (e.g., 5 = 5) and inequalities (e.g., 4 ≥ 3).
		- Also known as a *Boolean expression* because they create a Boolean answer or value when evaluated. Some common ones are: `> < >= <= == ~=`.
	+ A **logical operator** is a symbol or word used to connect two or more expressions such that the value of the compound expression produced depends only on that of the original expressions and on the meaning of the operator. Common logical operators include `and`, `or`, and `not`.
	+ A **ternary operator** does not exist in Lua.
		- It is generally is a shorthand way of writing an `ifelse` statement.
		- WikiText uses `#ifeq:PARAMETER|VARIABLE|THEN|ELSE`
		- But we can work around this as seen in the table below. This code works exactly like a ternary operator, and looks somewhat similar.
		- There's also no `#switch` statements in lua, but again you can workaround this with if and else statements.

## Wrong and Correct

```
canVote = age > 18 ? true : false
```
```
canvote = age > 18 and true or false
```

```
```

```

## Statements

```
if age < 16 then
  io.write("You can go to school", "\n")
  local localVar = 10
elseif (age <= 16) and (age < 18) then
  io.write("You can drive", "\n")
else
  io.write("You can vote", "\n")
end

```

* If the `if` statement doesn't come back as true, then you can write `else` or `elseif`.
	+ Anytime we have an `if` statement, we want to use an `end` at the bottom of wherever the chunk is finished.

## Running the code

* `$ lua luatut.lua` → `$ lua` invokes the lua language `luatut.lua` is the name of the lua file

```
age = 13
if (age < 14) or (age > 67) then io.write("You shouldn't work\n") end
```
```
$ lua luatut.lua
You shouldn't work

```
print(string.format("not true = %s", tostring(not true)))

```
```
$lua luatut.lua
not true = false

```
age = 13
canVote = age > 18 and true or false
io.write("Can I vote : ", tostring(canVote))

```
```
$lua luatut.lua
Can I vote : false$

```
quote = I changed my password to incorrect.
So that when I forget it, it always reminds me,
Your password is incorrect.

io.write("Quote Length ", #quote, "\n")
io.write("Replace I with me: ", string.gsub(quote, "I", "me"), "\n")
io.write("Index of password : ",string.find(quote, "password"), "\n")
io.write("Quote Upper : ", string.upper(quote), "\n")
io.write("Quote Lower : ", string.lower(quote), "\n")

```
```
$lua luatut.lua
Quote Length 111
Replace I with me: me changed my password to incorrect.
So that when me forget it, it always reminds me,
Your password is incorrect.
Index of password : 14
Quote Upper : I CHANGED MY PASSWORD TO (…)
Quote Lower : i changed my password to (…)

 A couple simple string operations that are common.
First, `#quote` or `string.len(quote)` will output how many letters are in a text.
Second, `string.gsub(quote, "I", "me")` will basically do a `ctrl` + `H` replace on your text. This will happen *after* it has counted how many characters there are.
Third, find any matching indexes with `string.find(quote, "password")`. Aka it will count which letter position in which password is placed in the quote.
Fourth, we can make the whole quote uppercase or lowercase with `string.upper(quote)` and `string.lower(quote)` respectively.

## Looping

* `while` will loop through a block of code as long as a specified condition is true.
	+ There's no `continue` statement in lua, whereas this is a thing in other programming languages.
	+ Another thing we can do, and this is more like the common `do while` loop in other languages, there's something else called the `repeat` statement.

Let's look at how looping works:

```
while (i < 10) {
  text +=
  "The number is " + i;
  i++;
}

```

```
i = 1
while (i <= 10) do
  io.write(i)
  i = i + 1

  if 1 == 8 then break end
end
print("\n")

```

```
$lua luatut.lua
1234567

```
* `while (i <= 10) do` means that while 1 ≤ 10, we want to continue executing code inside of our while loop.
* `io.write(i)` means that we just want to print out the value of `i`.
* And inside our while loop we ofc want to increment the value of `i` with `{{{1}}}`
* Finally we want to jump completely out of this loop and not continue looping through it anymore: `if i == 8 then break end`. Here `break` willl end the loop.
* Then we need to add another `end` that will actually end our while loop.

As you can see it only printed the digits 1-7, as we told the code to end the loop at 8 with `i == 8`

```
repeat
  io.write("Enter your guess : ")
  guess = io.read()
until tonumber(guess) == 15

```
* `io.read()` ← This is how easy it is to get keyboard input.
* `until` then go down to define the condition that this is going to continue looping. We want to conver the guess they made from string to number: `tonumber(guess)`

TADA! We've created a number guessing game, where the program will continue to ask the user to guess until they type 15. This function is known as a `do while` in other languages, but in lua it's called `repeat until`.

```
for i = 1, 10, 1 do
  io.write (i)
end

```

```
$lua luatut.lua
12345678910

```
1. `for i =` define an iterator, just like we did with the `while` loop. Then we're going to define a starting value `1,` , then an ending value `10,` , and finally how much it should increment each time `1`. This will result in `for i = 1, 10, 1`
2. You could also throw in a `break` statement in here as well.

```
months = {"January", "February",
"March", "April", "May", "June",
"July", "August", "September",
"October", "November", "December"}

for key, value in pairs(months) do
  io.write(value, " ")
end

```

```
$lua luatut.lua
January February March April May
June July August September
October November December

```
I'm showing this now, because I want to show how easy it is to cycle through all these different tables.
1. We'll call it `key` so you can see, and `value` because every table will have a value or if left empty an index by default.

You will see it will print out every different month with a space in between each.

## Tables

Speaking of tables, let's have a look at how that works. As said, tables is going to take the place of `array`s, dictionaries, tuples and such in other languages.

```
aTable = {}
for i = 1, 10 do
  aTable[i] = i
end

io.write("First : ", aTable[1], "\n")
io.write("Number of Items : ", #aTable, "\n")

```

```
$lua tut.lua
First : 1
Number of Items : 10

```
* We can add values to the table using a `for` loop like so: `for i = 1, 10 do`. We could add them on their own, but this a quick way to throw a bunch of values in there.
* Everything is going to be stored inside of an index. So this is going to increment through different values of `i` and will just assign those values to `i` (here *i* shorthand for *index*). So the very first index in our table is going to have the value of `1`.
 **Insert value** inside a table

```
table.insert(aTable, 1, 0)
io.write("First : ", aTable[1], "\n")
io.write("Tenth : ", aTable[10], "\n")

```

```
First : 0
Tenth : 9
```

You can see it will print `Tenth : 9` instead of 10 for the tenth index, since everything was moved up when `1` was became `0`
* `(aTable)` Find the table you want to insert into
* `(aTable, 1)` Define the index you want to insert into
 Convert **from table to string**
We can also convert the table into a string, and define how we want each item to be separated.

```
print(table.concat(aTable, ", "))

```

```
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
```
 **Remove item** at a specific index

```
table.remove(aTable, 1)
print(table.concat(aTable, ", "))

```

```
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
```

As you can see the `0` which was at index no. `1` has been removed.
* `(aTable)` define the table we want to remove from
* `(aTable, 1)` define the index we want to remove from

```
aMultiTable = {}
for i = 0, 9 do
  aMultiTable[i] = {}
  for j = 0, 9 do
    aMultiTable[i] [j] = tostring(i) .. tostring(j)
  end
end
io.write("Table[0] [0] : ", aMultiTable[0] [0], "\n")

for i = 0, 9 do
  for j = 0, 9 do
    io.write(aMultiTable[i][j], " : ")
  end
  print()
end

```

```
$ lua luatut.lua
Table[0][0] : 12
00 : 01 : 02 : 03 : 04 : 05 : 06 : 07 : 08 : 09 :
10 : 11 : 12 : 13 : 14 : 15 : 16 : 17 : 18 : 19 :
(…)

```

You can go in and play with how tables are set up in Lua, and how to use them.
* Then we use a `for` loop to come in and populate this whole entire thing
* `aMultiTable[i] = {}`  Then define an index which we will save inside of. This will also be a MultiTable
* Then create another `for` loop that's going to also populate this guy
* Then `aMultiTable[i][j]` inside that again. You'll be able to go in here and pull values from here using exactly the same thing.
* `aMultiTable[i][j] = tostring(i) .. tostring(j)` Let's say we want to store them as strings.
* Now we're going to be able to access the information stored inside of there as well, using indexes. Let's say table, and we want to get whatever is stored at 0,0 in our MultiTable: `io.write("Table[0] [0] : ", aMultiTable[0] [0])`
* Then we're going to use the exact same format for our for loop, to cycle through and print out all the items in our table.

## Functions

Functions are going to allow us to reuse our code, as well as better organize our code.

```
function getSum(num1, num2)
  return num1 + num2
end
print(string.format("5 + 2 = %d", getSum(5,2)))

```

```
$lua luatut.lua
5 + 2 = 7

```
* `function getSum` Give the function a name
* `function getSum()` If you want to pass values into a function to perform operations on them, we can do something like `(num1, num2)`
* `return num1` If you want to perform an operation and then send it back to whoever called for our function to operate.
* `print(string.format("5 0 2 = %d", getSum))` We could then go in here and
	+ I'm bouncing back and forth between using the `print` and `io.write` command, just to show you how to use them
* `("5 + 2 = %d")` If we want a decimal in there, we enter `%d`.
* `("5 + 2 = %d", getSum())` Then we would call our function with getSum like that
* `("5 + 2 = %d", getSum(5,2))` And then pass in 5 and 2, separated by a comma

```
function splitStr(theString)
  stringTable = {}
  local i = 1
  for str in string.gmatch(theString, "[^%s]+") do
    stringTable[i] = str
    i = i + 1
  end

```
* `splitStr(theString)` and it's going to receive a string passed into it
* We're then going to create a string table. I'm going to come back to these different things.
* `local i = 1` We want to define a local variable inside of this
* `for str in string.gmatch(theString)` Then let's cycle through the string, and store anything except spaces inside our table
* `(theString, "[^%s")` If we wanted to basically capture all the strings up until the point in which there is a space, what we're going to use is a percent sign: `"[^%s]"`.
	+ This is going to represent the beginning of a string, or a bunch of characters or numbers or whatever; that's what that little caret symbol represents `^`.
	+ And then a `%s`. This is what is known as a **regular expression**. I have tutorials on those.

Basically what we're saying is that we want to cycle through the string `theString`, that they pass into our function, and we want to start capturing characters `[^`, up until they reach a space `%s`. And that's what we're going to be storing inside of our `stringTable = {}`
* So we're cycling through the string, we're going to go `stringTable[i]`
	+ `[i]` for the index of our table
	+ `stringTable[i] = str` We're going to be pulling out each of those strings and storign them temporarily in a variable named `str`
 Now let's also show you how we can return multiple values from a function.

```
  return stringTable, i
end

```

```
splitStrTable, numOfStr = splitStr("The Turtle")
for j = 1, numOfStr do
  print(string.format("%d : %s", j, splitStrTable[j][i]))
end

```

```
$lua luatut.lua
5 + 2 = 7
1 : The
2 : Turtle
3 : nil

```

There's always an extra little nil inside of there when we create tables. We can fix this by changing `numOfStr` to `-1`.
* `= splitStr("The Turtle")` Then we'll call our function like this. Let's keep it simple by calling it something like "Turtle".
* `for j = 1, numOfStr do` We can then cycle through everything that was passed back inside of that table

That's how to call a function, make it return multiple different values, how to split a string into a table, and how to return that value over here and save it into different variables, and cycle through it. So this was multiple different ways to use functions inside of Lua.

## Variadic functions

This is how we're going to be able to receive an unknown number of parameters inside of our functions.

```
function getSumMore(...)
  local sum = 0
  for k, v in pairs{}
    sum = sum + v
  end
  return sum
end
io.write("Sum ", getSumMore(1,2,3,4,5,6), "\n")

```

```
$lua luatut.lua
Sum 21
```

And that's how we're able to pass in an unknown number of parameters and then use it.
2. Then we can do something like `local sum = 0`
3. We could then come in and do `for k, v in`. `k` is for key again, while `v` is for value. Then `in pairs`, as this is going to be passed in here as a table. Then we're going to put a curly brackets with three dots `pairs{...}`. It's going to automatically keep cycling through there depending on the number of attributes and parameters that were passe inside: `do`
4. Then we go `sum = sum` plus whatever value is passed inside → `+ v`.
5. Ofc end that with an `end`. After that's done go return the total sum `return sum`.
6. And then close off the function, and we could print this all on the screen. Call `getSumMore`. We're going to pass as many things in here as we could possibly ever want to, let's just keep it as six.

https://youtu.be/iMacxZQMPXs?t=1995
https://www.youtube.com/watch?v=iMacxZQMPXs&lc=UgxE9dkcy\_ka9y0lJIV4AaABAg

Another thing that's kind of interesting inside of lua is, a function is a variable in that we can store them under variable names as well as we store tables, and we can also pass and return them through functions.

```
doubleIt = function(x) return x * 2 end
print(doubleIt(4))

```

```
function outerFunc()
  local i = 0

  return function()
    i = i + 1
    return i
  end
end
getI = outerFunc()
print(getI())
print(getI())

```

How they store values as they're called multiple times.
2. Let's create local variable = 0. And then let's put an inner function inside of it, like `return function()`. And inside of this guy, let's increment the value of it, and then return. So this is a function inside of a function, it's a closure. Whenever we include an inner function, that function is actually going to remember any changes made to the vairable inside of the inner function.
3. Let's store our function inside of a variable called "getI": `getI = outerFunc()`. So there we've stored it inside of there, then we write `print(getI())` function. Then we do the exact same thing again. The reason why this is a closure, is because you're going to continue to increment and store the changing values of I that are inside of there as you can see right here. Value i starts off as 1, but whenever it is called a second time, it will increment it, even though we assigned the value of 0 right there.

Code Routine
Let's look at a similar thing. Very similar to threads in other programming languages, except that they cannot run in prallell. Code rutines are going to have a state of

https://youtu.be/iMacxZQMPXs?t=2209

## References

1. ↑ w:c:Dev:Lua templating/Getting started#Copying modules to another wiki
2. ↑ Mozilla: Identifier 2021
3. ↑ Programming in Lua: Some Lexical Conventions 2003
4. ↑ Steve's Teacher: Full Lua Programming Crash Course - Beginner to Advanced, 2021
5. ↑ 5.0 5.1 Kenneth Leroy Busbee Relational Operators
6. ↑ Derek Banas: Lua Tutorial, 2015
7. ↑ Kenneth Leroy Busbee and Dave Braunscweig: Logical Operators
8. ↑ W3 schools: JavaScript While Loop