Type Coercion in Lua

Type Coercion in Lua

5 min

“Type coercion” is the implicit or automatic conversion of a value from one type to another. In Lua, this is either from a string to a number or a number to a string.

Lua will automatically convert the string and number types to the correct format in order to perform calculations. For example, if you try to apply an arithmetic operation to a string, Lua will try to convert that string to a number first, otherwise, the operation will not work. If the string cannot be converted to a number, an error is raised.

During Concatenation

When the concatenation operator is used, Lua converts a number into a string. For example:

  • print("This is Lua version " .. 5.1 .. " we are using.")
    • Output: This is Lua version 5.1 we are using.
  • print("Pi: " .. math.pi)
    • Output: Pi: 3.1415926535898
  • print("Pi: " .. 3.1415927)
    • Output: Pi: 3.1415927

As shown above, during coercion, we do not have full control over the formatting of the conversion. To format the number as a string as we would like we can use the string.format() function. For example:

  • print(("%.3f"):format(5.1))
    • Output: 5.100
    • Note how there are three decimal places.
  • print("Lua version " .. ("%.1f"):format(5.1))
    • Output: Lua version 5.1

This is an explicit conversion using a function to convert the number, rather than coercion.

During Arithmetic

Something you must remember about coercion is that it should be avoided when possible. Just because it works doesn’t mean it is good practice to use it. There’s nothing wrong with not converting a number before sending it to a function that will still accept it anyways, for instance, but try to avoid coercion when you can.


  • print(100 + "7")
    • Output: 107
  • print("1000" + 234)
    • Output: 1234
  • print(234 + "1000")
    • Output: 1234
  • print("hello" + 234)
    • Output: attempt to perform arithmetic on a string value

You can see where a string can be converted to a number, the calculation succeeds. The string “hello” cannot be converted to a number and so an error occurs. In statically typed languages (e.g. C) this would cause an error as you cannot assign a value to a variable of an incompatible type. This works in Lua because it is dynamically typed.

During Comparisons

A notable exception: comparison operators (== ~= < > <= >=) do not coerce their arguments. The (in)equality operators consider a number to be not equal to its string representation (or any non-number type in fact). Ordered comparison operators throw an error when you feed them different types:

  • print(100 == "100")
    • Output: false
  • print(100 ~ "hello")
    • Output: true
  • print(100 ~ {})
    • Output: true
  • print(100 == tonumber("100"))
    • Output: true
  • print(100 < "100")
    • Output: attempt to compare number with string

Coercion of Other Types

Coercion does not only exist for numbers and strings. There are also other cases of coercion that apply in Roblox.


One example is enums. When you use a string or a number where an enum or a number is expected, it is coerced to an enum.

Here are three examples that all do the same things, they all create a Part and make it Concrete:

local p1 = Instance.new(**Part**)
p1.Material = 816
p1.Parent = workspace

local p2 = Instance.new(**Part**)
p2.Material = **Concrete**
p2.Parent = workspace

local p3 = Instance.new(**Part**)
p3.Material = Enum.Material.Concrete
p3.Parent = workspace


Another example of coercion is with the TimeOfDay property of the Lighting. This property sets the current time in the server, which defines whether it is night, day, or any other time. The TimeOfDay property is a string, but, if you send it a number as an argument, it will still work.

Here are two examples. One uses a number, and one uses a string. Both do the same thing:

game.Lighting.TimeOfDay = 5

Which outputs “05:00:00”

game.Lighting.TimeOfDay = "05:00:00"

Which outputs “05:00:00”

See Also

  • strings.
  • lua
  • coding
  • concept