What are Variadic Functions? How to use them

What are variadic functions? Well for a beginner, it is a function which can support any numbers of provided arguments.

This exist because Lua is built from C and C has variadic functions

Well to put simply, let me just show you an example

function variadic(...) --... is a symbol to represent one or more arguments
    return ...
end
print(variadic(true,"hi",2)) -- true,"hi",2

But variadic are much more powerful than that.

function sum(...:number) --we added : number so that the argument should only be a number and nothing else
      local sum = 0
      for i,v in pairs({...} do --putting brackets around ... will turn it into a table, ... will only return a number and not a table
          sum += v
      end
      return sum
end
print(add(1,1,1)) -- 3
print(add(1,"hi",1)) -- error

So what is this even useful for?
This can be useful for ability functions which need a specific argument


local abilities = {}
function abilities.ability1(pos)
end
function abilities.ability2(player,pos)
end

function doAbility(ability,argument)
     abilities[ability](argument)
end
doAbility("ability2",player,pos) -- we need two arguments but this function only supports one argument
doAbility("ability1",pos)

We can fix this by using variadic functions

local abilities = {}
function abilities.ability1(pos)
end
function abilities.ability2(player,pos)
end

function doAbility(ability,...)
     abilities[ability](...)
end
doAbility("ability2",player,pos)
doAbility("ability1",pos)

Fun Fact : I used to do this lol

--NEVER EVER DO THIS IN YOUR SCRIPTS!!!!!
local abilities = {}
function abilities.ability1(pos)
end
function abilities.ability2(player,pos)
end

function doAbility(ability,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)
     abilities[ability](arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)
end
doAbility("ability2",player,pos)
doAbility("ability1",pos)

Conclusion
Variadic functions are very useful. They can be very helpful in making math functions which can require more than one number. It can also be helpful to provide conflicting arguments to a function.

14 Likes

Thats super useful! Thank you for sharing! I always wondered how people got around putting like 30 one of arguments in functions.

How can we set up some arguments that are not listed in the initial function?
Ex.

function Create(parent, instance, ...)
	local args = {...}
	local obj = Instance.new(instance)
	obj.Parent = parent
	
	if obj:IsA("BasePart") then
		local size = ... -- How can this be defined?
		obj.Size = size
	end

    return obj
end

Also are variadic functions even used for things like the code above?
I see how it can be useful as to not needing to define every argument, but I am having trouble understanding its other use cases. TY

1 Like

Well you can just place it as the variable, you just need to know the specific order for each property.

--@ e.g.

local function Create(parent, instance, ...)
	local args = {...}
	local obj = Instance.new(instance)
	obj.Parent = parent

	if obj:IsA("BasePart") then
		obj.Size = args[1]
		obj.Anchored = args[2]
		obj.BrickColor = args[3]
	end
end

Create(workspace, "Part", 
	Vector3.new(5, 5, 5), -- args[1]
	true, -- args[2]
	BrickColor.Red() -- args[3]
)
1 Like

Rather than using variadic args, I would recommend a dictionary approach:

local function Create(instance, parent, properties)
    local obj = Instance.new(instance)
    for property, value in properties do
        obj[property] = value
    end
    obj.Parent = parent
    return obj
end

local part = Create("Part", workspace, {
    Size = Vector3.new(10, 10, 10),
    BrickColor = BrickColor.random(),
    Name = "My Part"
})
4 Likes

I occasionally use them, but could you provide an example of where I would need to use them over dictionaries? Also, are there any other ways to use/modify them, I thought that the …: number part was very cool, can you do that with strings or other methods?

A variadic function is very flexible to the size of its input. Using a dictionary type can be very messy as you don’t see any math functions using a dictionary approach. for the question of the :number ,this is called type checking, i recommend reading it here in the Lua-U documentation - Type checking - Luau

There aren’t any times when you need to use variadic args over lists or dictionaries. It’s a big reason why a lot of languages just don’t have support for it. They can be pretty convenient though.

An example of one of the more useful variadic functions is print:
print(a, b, c, d, e, f, etc)
As many arguments as you want. It could have been written to require a table
print({a, b, c, etc})
however that takes a little bit of extra work especially when you only want to print one thing.

lol I just started looking into vardic functions and saw this. I commented and then never used them.

The wrong usecase of a variadic function: