Coercion
What is Coercion?
Lua performs automatic conversion of numbers to strings and vice versa where it is appropriate. In computer science, this is called coercion.
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.
Examples:
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. e.g.:
Example:
Note how there are three decimal places.
This is explicit conversion using a function to convert the number, rather than coercion.
Using Coercion
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.
You can see where a string can be converted to 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.
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:
Coercion of Other Types
Coercion does not only exist for numbers and strings. There are also other cases of coercion that apply in ROBLOX.
Enums
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:
Instance.new('Part', Workspace).Material = 816
Instance.new('Part', Workspace).Material = 'Concrete'
Instance.new('Part', Workspace).Material = Enum.Material.Concrete
TimeOfDay
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 argument, it will still work.
Here are two examples. One uses a number, and one uses a string. Both do the same thing: