Skip to content

Instantly share code, notes, and snippets.

@5310
Last active May 14, 2025 17:00
Show Gist options
  • Save 5310/789aced1ff3de8cd3e59cab697d83b28 to your computer and use it in GitHub Desktop.
Save 5310/789aced1ff3de8cd3e59cab697d83b28 to your computer and use it in GitHub Desktop.
Basic functional programming for vanilla Lua
table.print = function(xs, indent)
indent = indent or ""
for k, v in pairs(xs) do
if type(v) == "table" then
print(indent .. tostring(k) .. " = {")
table.print(v, indent .. " ")
print(indent .. "}")
else
print(indent .. tostring(k) .. " = " .. tostring(v))
end
end
end
table.pairs = function(ps)
local result = {}
for k, v in pairs(ps) do
table.insert(result, { k, v })
end
return result
end
assert(table.pairs({ 10, 20, 30 })[3][2] == ({ { 1, 10 }, { 2, 20 }, { 3, 30 } })[3][2], 'table.pairs')
table.unpair = function(ps)
local result = {}
for _, pair in pairs(ps) do
result[pair[1]] = pair[2]
end
return result
end
assert(table.unpair({ { 1, 10 }, { 2, 20 }, { 3, 30, } })[3] == ({ 10, 20, 30 })[3], 'table.unpair')
table.keys = function(xs)
local result = {}
for k, _ in pairs(xs) do
table.insert(result, k)
end
return result
end
assert(table.keys({ 10, 20, 30 })[3] == 3, 'table.keys')
table.values = function(xs)
local result = {}
for _, v in pairs(xs) do
table.insert(result, v)
end
return result
end
assert(table.values({ 10, 20, 30 })[3] == 30, 'table.values')
table.bind = function(xs, b)
local result = {}
for k, v in pairs(xs) do
for _, p in pairs(b(k, v)) do
table.insert(result, p)
end
end
return table.unpair(result)
end
assert(table.bind({ 10, 20, 30 }, function(k, v) return { { k, v }, { 10 + k, 100 + v } } end)[13] == 130, 'table.bind')
table.map = function(xs, m)
local result = {}
for k, v in pairs(xs) do
result[k] = m(k, v)
end
return result
end
assert(table.map({ 10, 20, 30 }, function(_, v) return v * 100 end)[3] == 3000, 'table.map')
table.reduce = function(xs, r, acc)
local result = acc
for k, v in pairs(xs) do
result = r(k, v, result)
end
return result
end
assert(table.reduce({ 10, 20, 30 }, function(_, v, a) return a + v end, 0) == 60, 'table.reduce')
table.filter = function(xs, f)
local result = {}
for k, v in pairs(xs) do
if f(k, v) then
table.insert(result, { k, v })
end
end
return result
end
assert(table.filter({ 10, 20, 30 }, function(_, v) return (v % 3 == 0) end)[1][2] == 30, 'table.filter')
table.all = function(xs, f)
for k, v in pairs(xs) do
if not f(k, v) then
return false
end
end
return true
end
assert(table.all({ 10, 20, 30 }, function(_, v) return (v % 10 == 0) end), 'table.all')
table.has = function(xs, k)
return xs[k] ~= nil
end
assert(table.has({ a = 'alice', b = 'bob', c = 'charlie' }, 'c'), 'table.has')
table.contains = function(xs, v)
for _, _v in pairs(xs) do
if _v == v then
return true
end
end
return false
end
assert(table.contains({ a = 'alice', b = 'bob', c = 'charlie' }, 'charlie'), 'table.contains')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment