[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: The Curry Challenge
 
- From: Romulo Bahiense <romulo@...>
 
- Date: Thu, 11 Jan 2007 22:22:02 -0200
 
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.)
Challenge #2:  Write "curry" without using any tables!  ;)
(...)
That's a bit difficult to do in plain Lua, because you can't return 
multi values from a function and next to it return others values from 
another function :
f=function() return 1,2,3 end
print(f(),f())
> 1	1	2	3
And if you can't do that, and can't use tables, well...
The only solution I can think about, Rici already suggested, that is to 
create on the fly a function (using loadstring) that receives n 
parameters and return a closure that will return those n parameters plus 
the closure's varargs.
Something like:
function(f,a0,a1,a2,~~,an)
    return
    function(...)
        return f(a0,a1,a2,~~,an,...)
    end
end
("~~" means "..." as in math, not in Lua)
As the challenge didn't say anything about doing only on lua side or 
not... (untested, but using an almost identical code in production )
static int l_unwrap(lua_State L)
{
    int i = 1;
    while(lua_type(L,lua_upvalues(i))!=LUA_TNONE)
    {
        lua_pushvalue(L,lua_upvalue(i));
        lua_insert(L,i); /* First param first */
        i++;
    }
    return lua_call(L,lua_gettop(L)-1,LUA_MULTRET);
}
int l_wrap(lua_State *L)
{
    /* A sanity check here would be good */
    lua_pushcclosure(L,l_unwrap,lua_gettop(L));
    return 1;
}
...
lua_register(L, "wrap", l_wrap)
...
f = wrap(print,1,2,3)
f(4,5,6)
> 1	2	3	4	5	6
Pretty simple, uh?
--rb