[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
**Subject**: **Re: Another example for syntactically lightweight closures**
**From**: "steve donovan" <steve.j.donovan@...>
**Date**: Thu, 7 Feb 2008 13:50:55 +0200

On Feb 7, 2008 11:11 AM, steve donovan <steve.j.donovan@gmail.com> wrote:
> print(("|x,y| x+y")(2,3))
>
> print( ("|x,y| x+y")(20,30))
The implementation I presented was of course not optimal, as I
realized about 500ms after hitting send; the lookup was not in the
right place.
local llookup = {}
getmetatable('').__call = function(s,...)
local fun = llookup[s]
if not fun then
local args,body = s:match('%s*|(.-)|%s*(.+)')
if not args then
args = ''
body = s
end
local code = 'function('..args..') return '..body..' end'
print 'compiling'
code = "return " .. code
fun = assert(loadstring(code))()
llookup[s] = fun
end
return fun(...)
end
Looking at some timings, comparing '|x| <expr>' with function(x)
return <expr> end;
N = 1,000,0000
x
tring: took 3.23 sec
fun: took 1.13 sec
x*x
string: took 3.34 sec
fun: took 1.28 sec
sin(x)
string: took 7.92 sec
fun: took 5.52 sec
Basically we are paying for the extra function call (__call), but as
the payload takes more time, the difference narrows a lot.
steve d.