[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: The Curry Challenge
- From: Rici Lake <lua@...>
- Date: Thu, 11 Jan 2007 18:25:30 -0500
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"))