Team Shad - Lua

Welcome to Team Shad - Lua

Lua, known for its speed, efficiency, and versatility, has a rich history and is widely used across various industries. It incorporates data-description from Simple Object Language (SOL) while adding traditional programming control flow syntax from Modula, a descendant of Pascal. "Lua" means "Moon" in Portuguese, a play on "SOL" meaning "Sun". Lua is active and continuously being evolved becoming more of a powerhouse in scripting language.

Lua's speed and lightweight design make it a preferred choice for applications ranging from game development to embedded systems. Its adaptability across different programming paradigms, including procedural, object-oriented, and functional programming, provides developers with flexibility in crafting solutions tailored to their needs.

Lua's dynamic typing and excellent embeddability make it a standout choice for customization and extensibility. With automatic memory management through incremental garbage collection, Lua ensures efficient memory usage without manual intervention.

As you explore the features, comparisons, and examples on this page, you'll discover the breadth of Lua's capabilities and its significance in the world of scripting languages.

History of Lua

Lua was created in 1993 by members of Pontifical Catholic University of Rio de Janeiro, Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes who could not obtain customized software from outside of Brazil. Lua was created with the goal of being a powerful yet lightweight scripting language. Over the years, it has gained popularity in various domains, including game development, embedded systems, and scripting for applications. Lua's simplicity and efficiency have contributed to its enduring success and widespread adoption.

Lua's design principles prioritize ease of integration, making it a go-to choice for embedding in applications and platforms with resource constraints. Its journey from inception to becoming one of the fastest scripting languages showcases the commitment of its developers to deliver a versatile and efficient tool for programmers.

Industry Applications

Lua is extensively used in various industries, including game development, where its speed and flexibility shine. Its embeddable nature makes it a popular choice for scripting within game engines, allowing developers to enhance and customize game behavior. Some notable games that where Lua has been apart of are games such as Roblox, Garry's Mod, and World of Warcraft. There are other applications such as the web server Nginx, Wireshark, and Adobe Lightroom for similar reasons.

Lua is renowned for its speed, efficiency, and versatility, making it a preferred choice for various applications. Here are some key features that set Lua apart:

Comparison with Shell Scripting

Lua's capabilities extend beyond traditional shell scripting languages. Here's a comparison between Lua and a typical shell scripting language:

Feature Lua Shell Scripting
Performance High Varies, generally lower than Lua
Programming Paradigms Procedural, Object-Oriented, Functional Primarily Procedural
Typing Dynamic Dynamic/Weak
Embeddability Excellent Less Common
Memory Management Automatic Garbage Collection Manual

Comparison with Python

Lua and Python are both versatile scripting languages, but they have distinct characteristics. Here's a comparison between Lua and Python:

Feature Lua Python
Performance High Moderate to High
Programming Paradigms Procedural, Object-Oriented, Functional Procedural, Object-Oriented, Functional
Typing Dynamic Dynamic/Strong
Embeddability Excellent Embeddable, widely used in various applications
Memory Management Automatic Garbage Collection Automatic Garbage Collection

Comparison of Syntax

Lua's syntax is similar to other scripting languages, but it has some unique characteristics. Here's a comparison of syntax between Lua and other scripting languages:

Language Code
Lua -- global
num = 10

-- local
local name = "Lua"
Shell (Bash) # global
num=10

# local
local name="Bash"
Python # global - outside a function
num = 10

# local - inside a function
name = "Python"
Operators -- Lua
result = 5 + 3

# Shell (Bash)
result=$((5 + 3))

# Python
result = 5 + 3
If/Else/Else If -- Lua
if result >= 10 then
print("A")
elseif result >= 8 then
print("B")
else
print("C")
end

# Shell (Bash)
if [ "$result" -ge 10 ]; then
echo "A"
elif [ "$result" -ge 8 ]; then
echo "B"
else
echo "C"
fi

# Python
if result >= 10:
print("A")
elif result >= 8:
print("B")
else:
print("C")
For/While -- Lua
for i = 1, 5 do
print(result)
end

while true do
print(result)
end

# Shell (Bash)
for i in {1..5}; do
echo $result
done

while true; do
echo $result
done

# Python
for i in range(1, 5):
print(result)
while True:
print(result)
Functions -- Lua
function add(x, y)
return x + y
end

# Shell (Bash)
add(){
echo $(($1 + $2))
}

# Python
def add(x, y):
return x + y
Reading input -- Lua
name = io.read()

# Shell (Bash)
read name

# Python
name = input()

Installation Process

Lua is implemented in pure ANSI C and compiles unmodified in all platforms that have an ANSI C compiler. You only need the Lua library and the Lua header files to compile Lua programs. There are two main ways to install Lua on your machine.

Available Translators

Lua can be installed via the Linux Terminal. The commands to download and install Lua will depend on your Linux distribution. For example:

Debian/Ubuntu

Open a terminal window and run the following commands:

$ sudo apt update
$ sudo apt-get install lua

This will display a list of all different packages offers. The user must explicitly select one version to install. For the latest version run the following commands:

$ sudo apt update
$ sudo apt-get install lua5.4

If successfully installed. The Lua interpreter can be used directly in the terminal. Run the following commands to use the Lua interpreter:

$ lua
Lua 5.4.6 Copyright (C) 1994-2020 Lua.org, PUC-Rio
>

Building from source

Lua is a free software distributed in source code form. If you want to mess with the complier or build it yourself, you can build it from source. To build Lua, you need the library and the header files. You can download the latest release from the Lua website.

curl -R -O http://www.lua.org/ftp/lua-5.4.6.tar.gz
tar zxf lua-5.4.6.tar.gz
cd lua-5.4.6
make all test

Note: If you don't have curl, try wget. If you don't have tar, try gunzip and tar. If you don't have make, just use the files src/lua and src/luac.

Online Compilers

Getting Help

Lua's community is very active and friendly. You can get help from the Lua community in many ways:

Lua is a versatile programming language that finds application in numerous products and projects worldwide. Explore some of its notable use cases below:

Hello World

The first program that every programmer writes is the Hello World program. Lua is no different. Here is the Hello World program in Lua:

print("Hello World")

To run the program, save it in a file called hello.lua and run it with the command lua hello.lua. You should see the following output:

Hello World

If you are using the stand-alone Lua interpreter, all you have to do to run your first program is to call the interpreter (usually named lua) with the name of the text file that contains your program. If you are using the Lua interpreter as a shell, you can type your program and then press Ctrl+D (on Unix) or Ctrl+Z (on Windows) to signal the end of your program. The Lua interpreter will then run your program.

prompt> lua hello.lua

Factorial

The factorial of a number is the product of all the integers from 1 to that number. For example, the factorial of 6 is 1*2*3*4*5*6 = 720. Factorial is normally used in Combinations and Permutations (mathematics).

Here is a simple program to compute the factorial of a number:

function factorial(n)
  if n == 0 then
    return 1
  else
    return n * factorial(n-1)
  end
end

print(factorial(6))

To run the program, save it in a file called factorial.lua and run it with the command lua factorial.lua. You should see the following output:

720

List Files

Here is a simple program to list all the files in a directory:

for file in io.popen('ls -a'):lines() do
print(file)
end

To run the program, save it in a file called listfiles.lua and run it with the command lua listfiles.lua. You should see the following output:

.
..
assets
index.html
script.js
styles.css

Person/Student

Lua has NO classes!!!

-- Person "class"
Person = {}
function Person:new(name, age)
  local obj = { name = name, age = age }
  setmetatable(obj, Person)
  Person.__index = Person
  return obj
end
function Person:getName()
  return self.name
end

function Person:getAge()
  return self.age
end

function Person:toString()
  return self:getName() .. " " .. self:getAge()
end

-- Student "class" (inherits from Person)
Student = setmetatable({}, { __index = Person })

function Student:new(name, age, major)
  local obj = Person:new(name, age)
  setmetatable(obj, self)
  self.__index = self
  obj.major = major
  return obj
end

function Student:getMajor()
  return self.major
end

function Student:toString()
  return Person.toString(self) .. " " .. self:getMajor()
end

-- Main program
local pp = Person:new("Ann", 21)
local ss = Student:new("Bob", 22, "cs")
local ps = Student:new("Carla", 23, "math")

print("pp:getName() => " .. pp:getName())
print("ss:getName() => " .. ss:getName())
print("pp:toString() => " .. pp:toString())
print("ss:toString() => " .. ss:toString())
print("ps:getName() => " .. ps:getName())
print("ps:toString() => " .. ps:toString())

Sleep Sort

This program is a demonstration of coroutines in Lua. While there are libraries for Lua which allow coroutines to sleep, "vanilla" Lua does not have this so there is a bit of playing with the coroutines' ability to yield to accomplish the same effect as sleeping.

function sleep(q, i)
 local t0 = os.clock()
 while os.clock() - t0 <= i do coroutine.yield(false) end
 table.insert(q,i)
 couroutine.yield(true)
end

seq = {5,6,1,8,3,7}
coroutines = {}
q = {}

-- create the coroutines
for i = 1, #seq do
 table.insert(coroutines, coroutine.create(sleep))
end

-- start the coroutines for the first time
for i = 1, #coroutines do
 coroutine.resume(coroutines[i], q, seq[i])
end

-- resume the coroutines repeatedly, remove from table when complete
-- (fake multithreading)
while #coroutines > 0 do
 rem = {}

 for i = 1, #coroutines do
  status, done = coroutine.resume(coroutines[i])

  if done then
   table.insert(rem,i)
  end
 end

 for i = 1, #rem do
  table.remove(coroutines,rem[i])
 end
end

--print them
for i = 1, #q do
 io.write(q[i], " ")
end
print()

To run the program, save it in a file called sleep.lua and run it with the command lua sleep.lua. You should see the following output (after eight seconds):

1 3 5 6 7 8

Number Guessing Game

-- global variables for wins and losses

numWins = 0
numLoss = 0

-- generates a random number

function generate(min, max)
  return math.random(min, max)
end

-- main function

function play()   local min = 1
  local max = 10
  local userNum = nil
  local computerNum = nil
  local playerTurn = true
  local ongoing = true
  local playerWin = false
  print("")
  print("Computer and player take turns guessing each other's numbers.")
  print("Numbers are between 1 and 10. First to guess wins!")
  while(ongoing) do
    if playerTurn then
      computerNum = generate(min, max)
      playerTurn = false
      print("Your guess:")
      userNum = tonumber(io.read())
      while(userNum == nil) do
        print("Invalid input. Please enter a number.")
        userNum = tonumber(io.read())
      end
      print("The number was", computerNum)
      print("")
      if userNum == computerNum then
        playerWin = true
        ongoing = false
      end
    else
      computerNum = generate(min, max)
      playerTurn = true
      print("Computer guess created. What was your number?")
      userNum = tonumber(io.read())
      while(userNum == nil) do
        print("Invalid input. Please enter a number.")
        userNum = tonumber(io.read())
      end
      print("The guess was", computerNum)
      print("")
      if userNum == computerNum then
        playerWin = false;
        ongoing = false;
      end
    end
  end
  if playerWin then
    print("Your guess was correct! You win!")
    numWins = numWins + 1
  else
  print("Computer guessed correctly! Computer wins.")
  numLoss = numLoss + 1
  end
end

-- displays menu

function displaymenu()
  print("")
  print("---------- MENU ----------")
  print("p - play game")
  print("d - display wins")
  print("q - quit")
  print("--------------------------")
  print("")
end

-- processes menu input

function menu()
  local userChoice = "a"
  while(userChoice ~= "q" or "Q") do
    displaymenu()
    print("")
    print("What do you want to do?")
    userChoice = io.read()
    -- lua has no switch statements
    if userChoice == "p" then
      play()
    elseif userChoice == "q" then
      print("")
      break
    elseif userChoice == "d" then
      print("")
      print("Number of wins:", numWins)
      print("Number of losses:", numLoss)
      print("")
    else
      print("Invalid Input.")
      print("")
    end
  end
end

-- runs code

menu()

The code defines a number guessing game where the player takes turns guessing a random number generated by the computer. The player and the computer alternate turns, and the first to correctly guess the opponent's number wins. The game is menu-driven, allowing the player to play a round, display the number of wins and losses, or quit the game.

Bank

The provided Lua program consists of multiple files representing a basic banking system. Each file defines different components of the system, including accounts, a bank, customers, and specific types of accounts such as checking and savings accounts.

AbstractAccount.lua: Defines the abstract structure for an account, including methods for deposit, withdrawal, balance retrieval, interest accrual, and conversion to a string representation.

Bank.lua: Implements a simple bank that can manage accounts, accrue interest on all accounts, and convert the entire bank's information to a string representation.

CheckingAccount.lua: Extends the abstract account to represent a checking account, inheriting the methods defined in AbstractAccount.lua.

Customer.lua: Defines a customer with a name and a method to convert the customer information to a string.

SavingAccount.lua: Extends the abstract account to represent a savings account, inheriting methods from AbstractAccount.lua and adding interest accrual functionality.

The structure allows for creating bank accounts, managing them in a bank, and performing basic banking operations such as deposit, withdrawal, and interest accrual.

To use this program effectively, instantiate customer objects, create specific account types, add them to the bank, and perform operations as needed.

Customer.lua

Customer = {}

function Customer:new(name)
  O = {} -- create object if user does not provide one
  setmetatable(O, self)
  self.__index = self
  O.name = name
  return O
end

function Customer:toString()
  return self.name
end

AbstractAccount.lua

require "Customer"

AbstractAccount = {}

function AbstractAccount:new(number, customer, balance)
  NewAccount = {}
  (NewAccount, self)
  self.__index = self

  NewAccount.number = number
  NewAccount.customer = customer
  NewAccount.balance = balance

  return NewAccount
end

function AbstractAccount:deposit(amount)
  self.balance = self.balance + amount
end

function AbstractAccount:withdraw(amount)
  self.balance = self.balance - amount
end

function AbstractAccount:getBalance()
  return self.balance
end

function AbstractAccount:accrue(rate) end

function AbstractAccount:toString()
  return self.number .. ":" .. self.customer:toString() .. ":" .. self.balance
end

CheckingAccount.lua

require "AbstractAccount"

CheckingAccount = AbstractAccount:new()

function CheckingAccount:new(number, customer, balance)
  NewChkAcc = AbstractAccount:new(number, customer, balance)
  setmetatable(NewChkAcc, self)
  self.__index = self
  return NewChkAcc
end

SavingAccount.lua

require "AbstractAccount"

SavingAccount = AbstractAccount:new{interest = 0.0}

function SavingAccount:new(number, customer, balance)
  NewSavAcc = AbstractAccount:new(number, customer, balance)
  setmetatable(NewSavAcc, self)
  self.__index = self
  NewSavAcc.interest = 0.0
  return NewSavAcc
end

function SavingAccount:accrue(rate)
  self.interest = self.interest + (self.balance * rate)
  self.balance = self.balance + (self.balance * rate)
end

Bank.lua

require "CheckingAccount"
require "SavingAccount"

Bank = {accounts = {}}

function Bank:add(account)
  self.accounts[account.number] = account
end

function Bank:accrue(rate)
  for _, acc in pairs(self.accounts) do
    acc:accrue(rate)
  end
end

function Bank:toString()
  local retString = ""
  for _, acc in pairs(self.accounts) do
  retString = retString .. acc:toString() .. "\n"
  end
  return retString
end

This is an output example of the Bank program:

>require "Bank"
true >c=Customer:new("Tom")
> chkAcc = CheckingAccount:new("101", c, 100.0)
> savAcc = SavingAccount:new("102", c, 200.0)
> Bank:add(chkAcc)
> Bank:add(savAcc)
> print(Bank:toString())
102:Tom:200.0
101:Tom:100.0
> Bank:accrue(0.02)
> print(Bank:toString())
102:Tom:204.0
101:Tom:102.0