[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Syntactic sugar for function parameters
- From: Bret Victor <bret@...>
- Date: Mon, 5 Feb 2007 03:00:32 +0000 (UTC)
Ivan-Assen Ivanov <ivanassen <at> gmail.com> writes:
> throughout our code we frequently use the following construct:
>
> foobar( function() ..... end )
>
> where the anonymous function body is often very small.
Here's something that's only slightly insane:
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
F = setmetatable({}, { __index = function (t,k)
local functionDef = "return function " ..
string.gsub(k, "%)", ") return ", 1) ..
" end"
t[k] = assert(loadstring(functionDef))()
return t[k]
end })
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
double = F["(x) 2*x"]
assert( double(7) == 14)
add = F["(x,y) x + y"]
assert( add(1,2) == 3 )
add2 = F["(x,y) x + y"]
assert( add == add2 )
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- An even more streamlined syntax, at some efficiency cost:
function L (s) return F[s] end
multiply = L"(x,y) x * y"
assert( multiply(3,4) == 12 )
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
In general:
F["(parameters) expression"]
turns into:
function (parameters) return expression end
The disadvantage, obviously, is that you can't use external local
variables. But a significant advantage is that these anonymous
functions are *cached*, as shown in the add2 example above.
Normally, if you write
function calledManyTimes ()
foobar( function (a,b) return a + b end )
end
a new closure will be allocated every time calledManyTimes is called,
even though the anonymous function doesn't actually close over anything.
F["(a,b) a + b"] only allocates the first time.
-Bret