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 3:49 am GMT (diff)