What is function overloading?
Explanation
Here’s an example from Java, a language that provides function overloading:
public class Addition {
// Addition of two integers
public int add(int a, int b) {
return a + b;
}
// Addition of two strings
public String add(String a, String b) {
return a + b;
}
}
public static void main(String[] args) {
Addition addition = new Addition();
int addedInts = addition.add(3, 4); // addedInts = 7
String addedStrings = addition.add("My ", "String!"); // addedStrings = My String!
}
Many other programming languages have support for function overloading such as C#, C++, Swift, and Kotlin. Interestingly enough you can actually see function overloading in Roblox by typing out CFrame.new()
.
You’ll have 6 different CFrame constructors to choose from. This is an example of overloading.
Overload Module Examples
Add Example
Here’s an example creating an overloaded function allowing you to add both strings and numbers
local add = Overload.new()
add:overload({'number', 'number'}, function(a: number, b: number)
return a + b
end)
add:overload({'string', 'string'}, function(a: string, b: string)
return a .. ' ' .. b
end)
print(add(3, 5)) --> Outputs: 8
print(add('Hello', 'world')) --> Outputs: Hello world
XFrame Example
Here’s an example replicating the first four constructors of CFrame.new()
local XFrame = {}
XFrame.new = Overload.new()
XFrame.new:overload({}, function()
return CFrame.new()
end)
XFrame.new:overload({'Vector3'}, function(pos: Vector3)
return CFrame.new(pos)
end)
XFrame.new:overload({'Vector3', 'Vector3'}, function(pos: Vector3, lookAt: Vector3)
return CFrame.new(pos, lookAt)
end)
XFrame.new:overload({'number', 'number', 'number'}, function(x: number, y: number, z: number)
return CFrame.new(x, y, z)
end)
XFrame.new()
XFrame.new(Vector3.new(3, 4, 5))
XFrame.new(Vector3.new(1, 2, 3), Vector3.new(0, 100, 0))
XFrame.new(8, 9, 10)
API
-
Overload.new(): Overloadable
- Creates a new Overloadable
-
:overload(types: {[number]: any}, func: function): void
- Adds a new function to an Overloadable
Source
--[[
Overload by AstrealDev
Overloaded functions in Lua
------------------------------------------------------------------------------
local add = Overload.new()
add:overload({'number', 'number'}, function(a: number, b: number)
return a + b
end)
add:overload({'string', 'string'}, function(a: string, b: string)
return a .. ' ' .. b
end)
print(add(3, 5)) --> Outputs: 8
print(add('hello', 'world')) --> Outputs: hello world
]]
local Overload = {}
local RESTRICTED_MODE = false -- Forces the use of primitive-only types
local PRIMITIVE_TYPES = {
'nil',
'boolean',
'number',
'string',
'function',
'userdata',
'thread',
'table',
}
--[[
Utility function for comparing tables
]]
function compare(t1: {[number]: any}, t2: {[number]: any}): boolean
local isEqual = true
if (#t1 ~= #t2) then
return false
end
for index, value in ipairs(t1) do
local value2 = t2[index]
if (value ~= value2) then
isEqual = false
end
end
return isEqual
end
--[[
Create a new Overloadable
]]
function Overload.new()
local self
self = setmetatable({
overloads = {},
}, {
__index = Overload,
__call = function(t, ...)
local args = {...}
local providedTypes = {}
for index, value in ipairs(args) do
table.insert(providedTypes, typeof(value))
end
for _, overload in pairs(self.overloads) do
if (compare(overload.types, providedTypes)) then
return overload.callback(...)
end
end
error('No overload matching provided types.')
end,
})
return self
end
--[[
Add a new function to overload in an Overloadable
]]
function Overload:overload(types: {[number]: string}, func)
if (RESTRICTED_MODE) then
for _, value in ipairs(types) do
assert(table.find(PRIMITIVE_TYPES, value) ~= nil, value .. ' is not a valid type.')
end
end
for _, overload in pairs(self.overloads) do
if (compare(overload.types, types)) then
error('Cannot add overload as an overload with the same types already exists.')
end
end
table.insert(self.overloads, {
callback = func,
types = types
})
end
return Overload