|
Subject: Re: The Curry Challenge Newsgroups: gmane.comp.lang.lua.general Date: 2007-01-11 23:25:30 GMT (1 year, 18 weeks, 13 hours and 5 minutes ago)
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"))
|
|
|