User:JulienDethurens/Essays/Variadic functions

From Legacy Roblox Wiki
Jump to navigationJump to search

If you have some experience with ROBLOX Lua, and have been using it for some time, you probably know that some functions can accept an indefinite number of arguments. That includes the print function, but also the pcall function and the coroutine.resume function, as well as many others. You might even have once needed to use a such thing and have been forced to put as much arguments as you could, hoping you would never need more arguments than that... But did you know you could actually have made it so that it could accept an indefinite number of arguments? That's right, you can make a function accept an indefinite number of arguments!

It is done with vararg expressions. Functions that use this are called variadic functions, because they can accept an infinity of arguments.

To completely understand how variadic functions work, you have to first know exactly how arguments are handled in Lua.

In a function definition, there is only a certain number of arguments. When you call a function with fewer arguments than the ones present in the function definition, the other arguments get the value nil, to indicate they have not been specified. Rather, when you put more arguments than the ones present in the function definition, these are ignored.

This is always true. Well, unless the function is a variadic function. A function becomes a variadic function when its function definition contains three dots ("...") at the end of the list of the arguments, like this:

function foo(a, b, ...)
	print(a + b)
end

In this case, the extra arguments will not be ignored and will instead become reachable by the function through a vararg expression, which is also written as three dots. The value of a vararg expression is a list of all the extra arguments.

You can therefore access all the extra arguments like this:

function foo(a, b, ...)
	for _, arg in pairs({...}) do
		print(arg)
	end
end
foo(1, 2, 3, 4, 5, 1337, 9001, "Hello World!")

3 4 5 1337 9001

Hello World!

This is useful for functions that need to accept many arguments, which, ironically, often need to accept many arguments because they are going precisely to pass these arguments to another function.

Note that, if you want all the arguments to be contained in the value of the vararg expression, you can just not put any other argument, like this:

function foo(...)
	for _, arg in pairs({...}) do
		print(arg)
	end
end
foo(1, 2, 3, 4, 5, 1337, 9001, "Hello World!")

1 2 3 4 5 1337 9001

Hello World!

History

In Lua 5.0, variadic functions worked slightly differently. You still put the "..." in the function's definition, like you do in Lua 5.1, but you could then access all the arguments through a an hidden argument called arg, which was a table containing all the arguments.

However, in Lua 5.1, the arg argument was removed and replaced by the new syntax, which uses "..." as a list containing all the arguments.