<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Afun</id>
	<title>Module:fun - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Afun"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;action=history"/>
	<updated>2026-04-05T19:04:26Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:fun&amp;diff=474905&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;diff=474905&amp;oldid=prev"/>
		<updated>2025-11-04T17:47:14Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:47, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:fun&amp;diff=474904&amp;oldid=prev</id>
		<title>wikt&gt;SurjectionBot: (bot) slight optimization to 5.2 compat: prefer unpack to table.unpack</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;diff=474904&amp;oldid=prev"/>
		<updated>2025-04-24T11:36:47Z</updated>

		<summary type="html">&lt;p&gt;(bot) slight optimization to 5.2 compat: prefer unpack to table.unpack&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:fun&amp;amp;diff=474904&amp;amp;oldid=410665&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>wikt&gt;SurjectionBot</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:fun&amp;diff=410665&amp;oldid=prev</id>
		<title>Sware at 21:19, 8 January 2025</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;diff=410665&amp;oldid=prev"/>
		<updated>2025-01-08T21:19:15Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:fun&amp;amp;diff=410665&amp;amp;oldid=374535&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:fun&amp;diff=374535&amp;oldid=prev</id>
		<title>Sware at 18:23, 5 August 2024</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;diff=374535&amp;oldid=prev"/>
		<updated>2024-08-05T18:23:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:fun&amp;amp;diff=374535&amp;amp;oldid=171723&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:fun&amp;diff=171723&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local export = {}  local ustring = mw.ustring local libraryUtil = require &quot;libraryUtil&quot; local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMul...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:fun&amp;diff=171723&amp;oldid=prev"/>
		<updated>2019-11-09T15:22:56Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local ustring = mw.ustring local libraryUtil = require &amp;quot;libraryUtil&amp;quot; local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMul...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local ustring = mw.ustring&lt;br /&gt;
local libraryUtil = require &amp;quot;libraryUtil&amp;quot;&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
local iterableTypes = { &amp;quot;table&amp;quot;, &amp;quot;string&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
local function _check(funcName, expectType)&lt;br /&gt;
	if type(expectType) == &amp;quot;string&amp;quot; then&lt;br /&gt;
		return function(argIndex, arg, nilOk)&lt;br /&gt;
			return checkType(funcName, argIndex, arg, expectType, nilOk)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return function(argIndex, arg, expectType, nilOk)&lt;br /&gt;
			if type(expectType) == &amp;quot;table&amp;quot; then&lt;br /&gt;
				if not (nilOk and arg == nil) then&lt;br /&gt;
					return checkTypeMulti(funcName, argIndex, arg, expectType)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				return checkType(funcName, argIndex, arg, expectType, nilOk)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Iterate over UTF-8-encoded codepoints in string.&lt;br /&gt;
local function iterString(str)&lt;br /&gt;
	local iter = string.gmatch(str, &amp;quot;[%z\1-\127\194-\244][\128-\191]*&amp;quot;)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local function iterator()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local char = iter()&lt;br /&gt;
		if char then&lt;br /&gt;
			return i, char&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return iterator&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.chain(func1, func2, ...)&lt;br /&gt;
	return func1(func2(...))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--	map(function(number) return number ^ 2 end,&lt;br /&gt;
--		{ 1, 2, 3 })									--&amp;gt; { 1, 4, 9 }&lt;br /&gt;
--	map(function (char) return string.char(string.byte(char) - 0x20) end,&lt;br /&gt;
--		&amp;quot;abc&amp;quot;)											--&amp;gt; { &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot; }&lt;br /&gt;
function export.map(func, iterable, isArray)&lt;br /&gt;
	local check = _check &amp;#039;map&amp;#039;&lt;br /&gt;
	check(1, func, &amp;quot;function&amp;quot;)&lt;br /&gt;
	check(2, iterable, iterableTypes)&lt;br /&gt;
	&lt;br /&gt;
	local array = {}&lt;br /&gt;
	local iterator = type(iterable) == &amp;quot;string&amp;quot; and iterString&lt;br /&gt;
		or (isArray or iterable[1] ~= nil) and ipairs or pairs&lt;br /&gt;
	for i_or_k, val in iterator(iterable) do&lt;br /&gt;
		array[i_or_k] = func(val, i_or_k, iterable)&lt;br /&gt;
	end&lt;br /&gt;
	return array&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.mapIter(func, iter, iterable, initVal)&lt;br /&gt;
	local check = _check &amp;#039;mapIter&amp;#039;&lt;br /&gt;
	check(1, func, &amp;quot;function&amp;quot;)&lt;br /&gt;
	check(2, iter, &amp;quot;function&amp;quot;)&lt;br /&gt;
	check(3, iterable, iterableTypes, true)&lt;br /&gt;
	&lt;br /&gt;
	-- initVal could be anything&lt;br /&gt;
	&lt;br /&gt;
	local array = {}&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for x, y in iter, iterable, initVal do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		array[i] = func(y, x, iterable)&lt;br /&gt;
	end&lt;br /&gt;
	return array&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.forEach(func, iterable, isArray)&lt;br /&gt;
	local check = _check &amp;#039;forEach&amp;#039;&lt;br /&gt;
	check(1, func, &amp;quot;function&amp;quot;)&lt;br /&gt;
	check(2, iterable, iterableTypes)&lt;br /&gt;
	&lt;br /&gt;
	local iterator = type(iterable) == &amp;quot;string&amp;quot; and iterString&lt;br /&gt;
		or (isArray or iterable[1] ~= nil) and ipairs or pairs&lt;br /&gt;
	for i_or_k, val in iterator(iterable) do&lt;br /&gt;
		func(val, i_or_k, iterable)&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------&lt;br /&gt;
-- From http://lua-users.org/wiki/CurriedLua&lt;br /&gt;
-- reverse(...) : take some tuple and return a tuple of elements in reverse order&lt;br /&gt;
--&lt;br /&gt;
-- e.g. &amp;quot;reverse(1,2,3)&amp;quot; returns 3,2,1&lt;br /&gt;
local function reverse(...)&lt;br /&gt;
	-- reverse args by building a function to do it, similar to the unpack() example&lt;br /&gt;
	local function reverseHelper(acc, v, ...)&lt;br /&gt;
		if select(&amp;#039;#&amp;#039;, ...) == 0 then&lt;br /&gt;
			return v, acc()&lt;br /&gt;
		else&lt;br /&gt;
			return reverseHelper(function() return v, acc() end, ...)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- initial acc is the end of the list&lt;br /&gt;
	return reverseHelper(function() return end, ...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.curry(func, numArgs)&lt;br /&gt;
	-- currying 2-argument functions seems to be the most popular application&lt;br /&gt;
	numArgs = numArgs or 2&lt;br /&gt;
	&lt;br /&gt;
	-- no sense currying for 1 arg or less&lt;br /&gt;
	if numArgs &amp;lt;= 1 then return func end&lt;br /&gt;
	&lt;br /&gt;
	-- helper takes an argTrace function, and number of arguments remaining to be applied&lt;br /&gt;
	local function curryHelper(argTrace, n)&lt;br /&gt;
		if n == 0 then&lt;br /&gt;
			-- kick off argTrace, reverse argument list, and call the original function&lt;br /&gt;
			return func(reverse(argTrace()))&lt;br /&gt;
		else&lt;br /&gt;
			-- &amp;quot;push&amp;quot; argument (by building a wrapper function) and decrement n&lt;br /&gt;
			return function(onearg)&lt;br /&gt;
				return curryHelper(function() return onearg, argTrace() end, n - 1)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- push the terminal case of argTrace into the function first&lt;br /&gt;
	return curryHelper(function() return end, numArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
--	some(function(val) return val % 2 == 0 end,&lt;br /&gt;
--		{ 2, 3, 5, 7, 11 })						--&amp;gt; true&lt;br /&gt;
function export.some(func, t, isArray)&lt;br /&gt;
	if isArray or t[1] ~= nil then -- array&lt;br /&gt;
		for i, v in ipairs(t) do&lt;br /&gt;
			if func(v, i, t) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for k, v in pairs(t) do&lt;br /&gt;
			if func(v, k, t) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--	all(function(val) return val % 2 == 0 end,&lt;br /&gt;
--		{ 2, 4, 8, 10, 12 })					--&amp;gt; true&lt;br /&gt;
function export.all(func, t, isArray)&lt;br /&gt;
	if isArray or t[1] ~= nil then -- array&lt;br /&gt;
		for i, v in ipairs(t) do&lt;br /&gt;
			if not func(v, i, t) then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for k, v in pairs(t) do&lt;br /&gt;
			if not func(v, k, t) then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.filter(func, t, isArray)&lt;br /&gt;
	local new_t = {}&lt;br /&gt;
	if isArray or t[1] ~= nil then -- array&lt;br /&gt;
		local new_i = 0&lt;br /&gt;
		for i, v in ipairs(t) do&lt;br /&gt;
			if func(v, i, t) then&lt;br /&gt;
				new_i = new_i + 1&lt;br /&gt;
				new_t[new_i] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for k, v in pairs(t) do&lt;br /&gt;
			if func(v, k, t) then&lt;br /&gt;
				new_t[k] = v -- or create array?&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return new_t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.fold(func, t, accum)&lt;br /&gt;
	for i, v in ipairs(t) do&lt;br /&gt;
		accum = func(accum, v, i, t)&lt;br /&gt;
	end&lt;br /&gt;
	return accum&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-------------------------------&lt;br /&gt;
-- Fancy stuff&lt;br /&gt;
local function capture(...)&lt;br /&gt;
	local vals = { n = select(&amp;#039;#&amp;#039;, ...), ... }&lt;br /&gt;
	return function()&lt;br /&gt;
		return unpack(vals, 1, vals.n)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Log input and output of function.&lt;br /&gt;
-- Receives a function and returns a modified form of that function.&lt;br /&gt;
function export.logReturnValues(func, prefix)&lt;br /&gt;
	return function(...)&lt;br /&gt;
		local inputValues = capture(...)&lt;br /&gt;
		local returnValues = capture(func(...))&lt;br /&gt;
		if prefix then&lt;br /&gt;
			mw.log(prefix, inputValues())&lt;br /&gt;
			mw.log(returnValues())&lt;br /&gt;
		else&lt;br /&gt;
			mw.log(inputValues())&lt;br /&gt;
			mw.log(returnValues())&lt;br /&gt;
		end&lt;br /&gt;
		return returnValues()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
export.log = export.logReturnValues&lt;br /&gt;
&lt;br /&gt;
-- Convenience function to make all functions in a table log their input and output.&lt;br /&gt;
function export.logAll(t)&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		if type(v) == &amp;quot;function&amp;quot; then&lt;br /&gt;
			t[k] = export.logReturnValues(v, tostring(k))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
----- M E M O I Z A T I O N-----&lt;br /&gt;
-- metamethod that does the work&lt;br /&gt;
-- Currently supports one argument and one return value.&lt;br /&gt;
local func_key = {}&lt;br /&gt;
local function callMethod(self, x)&lt;br /&gt;
	local output = self[x]&lt;br /&gt;
	if not output then&lt;br /&gt;
		output = self[func_key](x)&lt;br /&gt;
		self[x] = output&lt;br /&gt;
	end&lt;br /&gt;
	return output&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- shared metatable&lt;br /&gt;
local mt = { __call = callMethod }&lt;br /&gt;
&lt;br /&gt;
-- Create callable table.&lt;br /&gt;
function export.memoize(func)&lt;br /&gt;
	return setmetatable({ [func_key] = func }, mt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>