Lua Functors

lua-users home
wiki

This page describes some utility functions that are useful for working with functors in Lua. A functor is any callable entity, which includes functions and objects that define the "function" tag method.

[!] 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)


Contributors: JohnBelmonte
RecentChanges · preferences
edit · history
Last edited January 2, 2007 3:56 am GMT (diff)