lua-users home
lua-l archive

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



On 11-Jan-07, at 4:01 PM, Bret Victor wrote:

Challenge #1:  Write "curry".  (You may assume that none of the values
are nil, since nil and ... don't play nice together.)

OK, this one works with nil, but it definitely tests the length of ... and uses different code for different lengths. On the other hand, the different code is not explicit, and the generation is reasonably efficient thanks to Memoize (included below):

function Memoise(fn)
    return setmetatable({},
      {
       __index = function(t, k)
                   local val = fn(k); t[k] = val; return val
                 end,
       __call  = function(t, k)
                   return t[k]
                 end
      })
end

local concat = table.concat
Arglist = Memoise(
  function(n)
    local t = {}
    for i = 1, n do t[i] = "a"..i end
    return function(c) return concat(t, c) end
  end
)

Partial = Memoise(
  function(n) return loadstring(
"return function(f, "..Arglist[n]", "..") return function(...) return f("..Arglist[n]", "..", ...) end end"
    )()
  end
)
Partial[0] = function(f) return f end

function partial(f, ...) return Partial[select("#", ...)](f, ...) end

print123 = partial(print, 1, 2, 3)
printdcba = partial(print, "d", "c", "b", "a")
print123("foo", "bar")
printdcba(1, 3)

---- Here's another application of Arglist, to produce efficient string catenators:


Catter = Memoise(
  function(n) return loadstring(
"return function("..Arglist[n]", "..") return "..Arglist[n]"..".." end"
    )()
  end
)

c6 = Catter[6]
print(c6("a", "b", "c", "d", "e", "f"))