Memoize Function
This commit is contained in:
		
							parent
							
								
									3c8c64c6bf
								
							
						
					
					
						commit
						d33951b713
					
				
					 1 changed files with 68 additions and 0 deletions
				
			
		
							
								
								
									
										68
									
								
								ModuleScripts/Memoize.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								ModuleScripts/Memoize.lua
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
--[[
 | 
			
		||||
	memoize creates a function as a wrapper that caches the last outputs of a function.
 | 
			
		||||
	This is useful if you know that the function should return the same output every
 | 
			
		||||
	time it is run with the same inputs. The function should only return an output, and
 | 
			
		||||
	not have any side effects. These side effects are not cached.
 | 
			
		||||
 | 
			
		||||
	Without memoize's caching, even though the function ouputs the same values, the
 | 
			
		||||
	memory locations of the values are different; tables made in the function, even if
 | 
			
		||||
	they have the same values, won't be the same tables.
 | 
			
		||||
 | 
			
		||||
	memoize only caches the last set of inputs and ouputs. This means that it is only
 | 
			
		||||
	helpful when the function is likely to be called with the same inputs multiple
 | 
			
		||||
	times in a row. This is the case with most Roact use cases.
 | 
			
		||||
 | 
			
		||||
	Note that memoize only does a   ** shallow check on table inputs **   . This means
 | 
			
		||||
	that if the same table is input but the elements of the table are different then
 | 
			
		||||
	it will be assumed that the table has not changed.
 | 
			
		||||
 | 
			
		||||
	In addition to all the previous warnings, memoize strips trailing nils. This means
 | 
			
		||||
	that if foo is a memoized function and we call foo(), then foo(nil) will return a
 | 
			
		||||
	cached value. This is opposed to how print handles input. print() only outputs a
 | 
			
		||||
	new line, but print(nil) outputs "nil". This is because varargs can detect the
 | 
			
		||||
	number of arguments passed in. So, be careful when using memoize with varargs.
 | 
			
		||||
	Trailing nils will be stripped.
 | 
			
		||||
 | 
			
		||||
	The wrapper can take any number of inputs and give any number of outputs.
 | 
			
		||||
	Leading and interspersed nils are handled gracefully. Trailing nils on the input
 | 
			
		||||
	are stripped.
 | 
			
		||||
]]
 | 
			
		||||
local function captureSize(...)
 | 
			
		||||
	return {...}, select("#", ...)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function memoize(func)
 | 
			
		||||
	assert(type(func) == "function", "memoize requires a function to memoize")
 | 
			
		||||
 | 
			
		||||
	local lastArgs
 | 
			
		||||
	local lastNumArgs
 | 
			
		||||
	local lastOutput
 | 
			
		||||
	local lastNumOutput
 | 
			
		||||
 | 
			
		||||
	return function(...)
 | 
			
		||||
		local numArgs = select("#", ...)
 | 
			
		||||
 | 
			
		||||
		while numArgs > 0 and select(numArgs, ...) == nil do
 | 
			
		||||
			numArgs = numArgs - 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if numArgs ~= lastNumArgs then
 | 
			
		||||
			lastArgs = {...}
 | 
			
		||||
			lastNumArgs = numArgs
 | 
			
		||||
			lastOutput, lastNumOutput = captureSize(func(...))
 | 
			
		||||
			return unpack(lastOutput, 1, lastNumOutput)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		for i = 1, lastNumArgs do
 | 
			
		||||
			if select(i, ...) ~= lastArgs[i] then
 | 
			
		||||
				lastArgs = {...}
 | 
			
		||||
				lastOutput, lastNumOutput = captureSize(func(...))
 | 
			
		||||
				break
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		return unpack(lastOutput, 1, lastNumOutput)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
return memoize
 | 
			
		||||
		Loading…
	
		Reference in a new issue