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 2:56 am GMT (diff)