lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello,

I'm looking for a little memoize function [1] that supports multiple arguments and multiple return values, including nils.

The wiki [2] sports a couple of examples and pointers to various implementations (e.g. penlight's pl.utils.memoize [3], kikito's memoize.lua [4], etc), but at first glance they don't seem to support various combinations of arguments and return values...

Any suggestions?

Here is what I have so far:

local function Concat( aList, aSeparator, aStart, anEnd )
  local aBuffer = {}

  for anIndex = aStart or 1, anEnd or #assert( aList, 'bad argument #1 to \'Concat\' (table expected, got nil)'  ) do
    aBuffer[ #aBuffer + 1 ] = tostring( aList[ anIndex ] ) or 'nil'
  end

  return table.concat( aBuffer, aSeparator )
end

local function Memoize( aFunction )
  local aCache = {}

  assert( aFunction, 'bad argument #1 to \'Memoize\' (callable expected, got nil)' )

  return function( ... )
    local someArguments = table.pack( ... )
    local aKey = Concat( someArguments, '|', 1, someArguments.n )
    local aValue = aCache[ aKey ] or table.pack( aFunction( ... ) )

    aCache[ aKey ] = aValue

    return table.unpack( aValue, 1, aValue.n )
  end
end

local open = Memoize( io.open )
local gsub = Memoize( string.gsub )
local modf = Memoize( math.modf )
local concat = Memoize( table.concat )
local pack = Memoize( table.pack )

print( open( 'TestMemoize.lua', 'rb' ) )
print( open( 'TestMemoize.lua', 'rb' ) )
print( open( 'TestMemoize.lua', 'rb' ) )
print( gsub( '1 2 3', '%d+', '%1!' ) )
print( gsub( '1 2 3', '%d+', '%1!' ) )
print( gsub( '1 2 3', '%d+', '%1!' ) )
print( modf( 1.2 ) )
print( modf( 1.2 ) )
print( modf( 1.2 ) )
print( modf( 3.4 ) )
print( modf( 3.4 ) )
print( modf( 3.4 ) )

local aTable = {  1, 2, 3, 4, 5, 6 }
print( concat( aTable ) )
print( concat( aTable ) )
print( concat( { 1, 2, 3, 4, 5, 6 } ) )
print( concat( aTable, '.' ) )
print( concat( aTable, '.' ) )
print( concat( aTable, ':' ) )
print( concat( aTable, ':' ) )
print( concat( aTable, ';' ) )
print( concat( aTable, ';' ) )
print( pack( 1, 2, 3, 4, 5, 6 ) )
print( pack( 1, 2, 3, 4, 5, 6 ) )
print( pack( nil, nil, nil, 1, 2, 3, 4, 5, 6, nil, nil, nil ) )
print( pack( nil, nil, nil, 1, 2, 3, 4, 5, 6, nil, nil, nil ) )


> file (0x7fff74b510a0)
> file (0x7fff74b510a0)
> file (0x7fff74b510a0)
> 1! 2! 3!	3
> 1! 2! 3!	3
> 1! 2! 3!	3
> 1	0.2
> 1	0.2
> 1	0.2
> 3	0.4
> 3	0.4
> 3	0.4
> 123456
> 123456
> 123456
> 1.2.3.4.5.6
> 1.2.3.4.5.6
> 1:2:3:4:5:6
> 1:2:3:4:5:6
> 1;2;3;4;5;6
> 1;2;3;4;5;6
> table: 0x7fe02040b4b0
> table: 0x7fe02040b4b0
> table: 0x7fe02040bbf0
> table: 0x7fe02040bbf0


[1] http://en.wikipedia.org/wiki/Memoization
[2] http://lua-users.org/wiki/FuncTables
[3] https://github.com/stevedonovan/Penlight/blob/master/lua/pl/utils.lua#L339
[4] https://github.com/kikito/memoize.lua/blob/master/memoize.lua