Expression Templates In Lua

lua-users home
wiki

Expression templates is a technique used in C++ for passing expressions as function arguments and manipulating those expressions. [Veldhuizen] Further background information can be found in [1][2].

Here is an example of using an expression-template-like technique in Lua.

-- Expression object.

local expression_mt = {}

function Expression(name)

  return setmetatable(

    {name=name, eval=function(vars) return vars[name] end},

    expression_mt)

end

local function eval(o, vars)

  if type(o) == 'table' then return o(vars) else return o end

end

function expression_mt.__add(a, b)

  return setmetatable(

    {eval=function(vars) return eval(a, vars) + eval(b, vars) end},

    expression_mt)

end

function expression_mt.__pow(a, b)

  return setmetatable(

    {eval=function(vars) return eval(a, vars) ^ eval(b, vars) end},

    expression_mt)

end

function expression_mt.__call(a, vars)

  return a.eval(vars)

end



-- auto-create expression objects from globals

local G_mt = {}

function G_mt:__index(k)

  return Expression(k)

end

setmetatable(_G, G_mt)



-- example usage:



local function sum(expr, first, last)

  local result = 0

  for x=first,last do

    result = result + expr{x=x}

  end

  return result

end



print( sum(x^2 + 1, 1, 10) )  --> 395

Compare:

print( sum(x^2 + 1, 1, 10) )

with a more conventional approach:

print( sum(function(x) return x^2 + 1 end, 1, 10) )

In the latter case, the function "function(x) return x^2 + 1 end" is a black box to the function sum (bar sum doing string.dump on the function and examining bytecodes). sum can merely invoke the function but cannot see the implementation inside it. In the former case, the individual operations inside x^2 + 1 can be made accessible to sum.

To illustrate the power of this, the example could be rewritten in order to do symbolic integration on expressions [1]:

print( integral(x^2 + 1) )  --> expression object representing the

                            --- polynomial (1/3)*x^3 + x



print( sum(integral(x^2 + 1), 1, 10 )  --> 1063.333...

Note that Lua operations not supporting metamethods (e.g. and/or/not) cannot necessarily be used inside expressions in this technique.

--DavidManura

See Also


RecentChanges · preferences
edit · history
Last edited May 7, 2009 2:49 am GMT (diff)