§ root / a / hello-lua

Hello Lua

Lua language quickstart.

Let’s learn some Lua.

Lua (not LUA) is an elegant language with a simple syntax. It’s widely used by games developers. Lua is easy to embed in other programs so you might surprised the places you’ll run into it!

Let’s do hello world.

print "Hello World"

Pretty easy. print is a function, and "Hello World" is a string.

In Lua, functions are first class objects, which means you can mess with them.

myPrint = print
myPrint "Hello World"

Cool, right? We’ve assigned print to a different variable name. Let’s go back to the types.

print(type(print))
print(type("Hello World"))

What do you think this prints out?

If you guessed “function” and “string”, well done! Let’s talk a little more about strings.

Strings in Lua are immutable. That means you cannot change a string, ever, they are pure and unchanging.

str = "Hello World"
print(str)
str = "Hello World" .. "!"
print(str)

As you might guess, this prints out “Hello World”, then “Hello World!”. The .. is Lua’s concatenate operator. The .. operator doesn’t change either string instead it creates a brand new string by combining it’s two arguments.

If you understand that, you’ll be able to guess what is printed in this following piece of code.

str = "Hello World"
strB = str
strB = string.reverse(strB)
print(str, strB)

Hopefully you guessed correctly; the output is “Hello World”, “dlroW olleH”. Strings cannot be changed. The reverse function creates a new string and it’s then assigned to variable name strB. The original "Hello World" assigned to str doesn’t change it’s value. Let’s take a look some numbers next.

num = 1
numB = num
numB = numB + 1
print(num, numB)

Much like the strings above, this prints “1 2”, like you’d expect from any programming language. Why didn’t I use numB++? Because this operator doesn’t exist in Lua! Lua is simple and that’s not a negative, it makes it very easy to reason about.

We’ve touched on a few types now; string, function (briefly) and number. That’s nearly ALL the types! In a few brief paragraphs we’ve nearly covered the entire language.

So what’s missing? Well there’s nil, which has a similar meaning to null in some other languages.

print(nil)
print(nil or "Nothing")

Can you guess what this prints? It’s cheating a little. or is Lua’s boolean or operator, || in the C family of languages (from this I imagine you can guess it’s and and not not && and !. That’s quite a tricky sentence to parse!)

The statement some_variable or "default" is a Lua idiom for assigning default variables. If the first argument is nil, then the or statement returns the second argument. In the example “Nothing” is the default value. Let’s spell this out a bit, while also learning about functions and the if-statement.

    function NamedHello(name)

        if name == nil then
            name = "Mister"
        end

        print ("Hello " .. name)
    end

    print(NamedHello("Dave"))
    print(NamedHello())

Hey, we introduced a lot here. This shows one way to define a function in Lua. It takes in one parameter; name. If name is nil, we assign name the value of “Mister”. And as you can probably guess; it prints out “Hello Dave” when “Dave” is passed in as an argument and “Hello Mister” when nothing is passed as an argument.

Also note that Lua uses end to mark the end of functions and if-statements. The if-statement also requires then to mark the start of the inner block of code.

Let’s take the code we just wrote and make it idiomatic Lua.

function NamedHello(name)

    name = name or "Mister"

    print ("Hello " .. name)
end

print(NamedHello("Dave"))
print(NamedHello())

Cool, right? This is a shorter more readable way to give parameters default values.

Remember I mentioned that Lua functions are first-class objects? That means we can create them at runtime, and return them from other functions! This can be a little mind-bending if you’ve not programmed in such a language before. Let’s create a toy function-creating-function to demonstrate this.

function CreateSayPrint(sayer)
    sayer = sayer or "Mysterious Stranger"
    return function(str)
        print(sayer .. " > " .. str)
    end
end

danPrint = CreateSayPrint("dan")
jeffPrint = CreateSayPrint("jeff")
strangerPrint = CreateSayPrint()

danPrint("Hi there.")
jeffPrint("Hola.")
strangerPrint("*grunt*")
danPrint("Ok then...")

As I said, if you haven’t seen this before, it can be pretty mind-bending. But lots of people use Javascript as a first language these days and I believe it works in a similar way. So what does it print? You should be able to work it out but here’s the output.

dan > Hi there.
jeff > Hola.
Mysterious Stranger > *grunt*
dan > Ok then...

Wow it’s like an amazing skit producer. The CreateSayPrint function takes in the name of a person and then returns a custom print function that prepends the persons name to whatever’s passed into the print.

Functions can return functions.

function Hello1()
    print("Hello")
end

function Hello2()
    return function()
        print("Hello2")
    end
end

function Hello3()
    return function()
        return function()
            print("Hello3")
        end
    end
end

Hello1()
Hello2()()
Hello3()()()
print(type(Hello3()))

Each of these calls prints out hello, apart from the last one. The last function prints out “function” because that’s what’s returned from Hello3. Let’s make that a little more explicit.

h1 = Hello3()
h2 = Hello3()()

Hello3()()()
h1()()
h2()

Each of these prints out “Hello3”!

I don’t want this quick start to get too long, so let’s look at Lua’s one and only data structure: the table. Oh actually before that - there’s another type we haven’t touched; booleans but they’re pretty straight forward.

print(true)
print(false)

booleansArePrettySimple = true

if booleansArePrettySimple then
    print("The end of introducing booleans.")
end

Ok back to tables. Because tables are cool. Do you know everything we’ve written so far exists INSIDE A TABLE! That’s right. But I’m sworn to secrecy and will not reveal it’s name, at least not during this quickstart. Tables!

fruit =
{
    "oranges",
    "pears",
    "apples"
}
print(type(fruit))
print(fruit)

What do the prints do? The first one is pretty easy - it prints out “table”. Those squiggly brackets are how you define a table. The second print tries to print out the value of the table. Tables can be quite complicated in Lua, so Lua doesn’t even try to print out the table contents, instead it prints out something like.

table: 0x812e30

This isn’t useful. This is the tables position in memory. So how do we print out the table contents? For loops!

for k, v in pairs(fruit) do
    print(k, v)
end

A few things to note here - two values k and v, these stand for key and value, there’s a keyword pairs which we’ll totally ignore for now - just assume it’s magic that makes the for-loop work and the for-loop requires a do and end for the code block.

This prints out.

1 oranges
2 pears
3 apples

Almost like we’d expect. Lua indexes tables from 1 not 0, like in other languages. This means

print(fruit[0]) -- nil
print(fruit[1]) -- oranges

Square brackets can be used to index a table. We’re using a number, these are kind of an implicit key. Let’s make things explicit.

fruit =
{
    [1] = "oranges",
    [2] = "pears",
    [3] = "apples",
}

This is the same table. In theory Lua tables are all key/value tables. You add things to the table, the values, by giving it a name, the key. Then later you can get the value out by passing in the key. The reality is a little more nuanced but we’ll leave that for now.

Tables are Lua’s only data structure. They’re not just for strings. Let’s make a new table, a crazy table.

crazy_table =
{
    favourite_animal = "dog",
    [true] = "Sausages",
    [1.099] = print,
    nested_table =
    {
        {},
        {},
        {},
    }
}

for k, v in pairs(crazy_table) do
    print(k, v)
end

-- Whattttt?
crazy_table[1.099]("Hello World")

Can you guess what this prints? Maybe this was too crazy a table to spring on you at this point :D Run the code and find out.

Let’s look at a more sane table.

people =
{
    bruce =
    {
        parents =
        {
            father = "Thomas",
            mother = "Martha"
        },
        age = 15,
    },
    alfred =
    {
        parents =
        {
            father = "Unknown",
            mother = "Unknown",
        },
        age = 42
    }
}

Creating data structures in Lua is really intuitive, this table describes a family. Let’s print out some data.

print("Bruce's age:", people.bruce.age)
print("Alfred's age:", people.alfred.age)

This is as you’d expect. Imagine there were 300 people - how could print out all their names? For loops to the rescue again, let’s use string.format too!

for k, v in pairs(people) do
    print(string.format("%s's age: %d", k, v.age))
end

The key in our for-loop is the name of the person and the value is the sub-table describing that person. We can get the age of the person from the sub-table by using the . syntax.

Can you print out their parents in a similar way?

If you’ve read this far - well done, you know a good amount of Lua. Enough to start getting stuff done and learning more. I hope it’s sparked your interest to delve in a little deeper into the language.

Related Articles