Lua Functors |
|
[!] VersionNotice: The code on this page is Lua 4.0 and is not compatible with Lua 5.
It's often useful to bind argument values to a functor. [explain]
-- Bind - given functor and set of arguments, generate binding as new functor -- function Bind(functor, ...) local bound_args = arg return function(...) local all_args = { } AppendList(all_args, %bound_args) AppendList(all_args, arg) return call(%functor, all_args) end end -- BindFromSecond -- -- This version skips the first argument when binding. -- It's useful for object method functors when you want to leave the object -- argument unbound. -- function BindFromSecond(functor, ...) local bound_args = arg return function(...) local all_args = { arg[1] } AppendList(all_args, %bound_args) AppendList(all_args, arg, 2, -1) return call(%functor, all_args) end end
Chaining of functors also comes in handy. [explain]
-- Chain - generate functor that is chain of input functors -- -- Return value of output functor is result of last input functor in chain. -- function Chain(...) local funs = arg local num_funs = getn(funs) return function(...) local result for i=1, %num_funs do result = call(%funs[i], arg) end return result end end
Here are some tests showing use of the interface above along with expected output.
function a(n, s) print("a("..n..", "..s..")") end function b(n, s) print("b("..n..", "..s..")") end MyClass = { } function MyClass.test(self, n, s) print("MyClass.test("..n..", "..s..")") end c = Bind(a, 5) d = Bind(a, 10, "ten") e = BindFromSecond(MyClass.test, 123) f = Chain(a, b, a) c("five") --> "a(5, five)" d() --> "a(10, ten)" -- assuming obj is an instance of MyClass e(obj, "abc") --> "MyClass.test(123, abc)" f(66, "chain") --> "a(66, chain)" --> "b(66, chain)" --> "a(66, chain)"
Since there was a rally call to make a "stdlua" library, I thought it was due time to fill in the implementation of these functions. There is one dependency (AppendList
) not shown. I'm sure some better list utilities will be created for the library than what I have. Anyway the prototype follows. --JohnBelmonte
-- AppendList - add items in list b to end of list a -- -- Optional closed range [from, to] may be provided for list b. Negative -- index counts from end of table. -- function util.AppendList(ta, tb, from, to)