lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Wed, Oct 30, 2002 at 11:25:14AM -0700, C.S. Brooks wrote:
> What do upvalues do? How do they work? Where might I use them?

They are Lua's (pre 5.0) answer to lexical scoping and closures from
functional programming languages. You need them whenever you want to
access a local variable in an outer scope. A common application is,

function dosomething(table)
   local a = 12
   foreach(table, function(key, value) print(key, value + %a) end)

The inner function that prints the key and adds 12 to each value
accesses the variable "a" from the outer scope. The only way to do
this in Lua pre-5.0 is by treating "a" as an upvalue.

Another application is for creating function objects. Suppose you have
something like this:

function make_addn(n)
  return function(a)
           return a + %n

This is basically the equivalent of a closure in a functional
programming language. make_addn creates a function that adds a fixed
number to its argument. This fixed number is parameterizable. It could
be used like this:

add1 = make_addn(1)
add5 = make_addn(5)

print(add1(3))  --> 4
print(add5(3))  --> 8

Function objects and closures look esoteric on a first glance, but are
in fact an extremely powerful concept. It takes a certain frame of
mind to use them effectively, but once you do, you will start to
wonder how you could live without them before. :-)

In all this it is important to realize that upvalues are evaluated at
the time when you create the function. As a result, they are
immutable. In other words, you cannot assign to them from within the

If an upvalue is a table, you cannot assign a new table to
it. However, you *can* change any entry *inside* that table. This
allows you to create functions that remember a value, much like C's
"static" keyword. In C something like:

int generate_number(void)
  static int number = 0;
  return number++;

would correspond to the following in Lua:

  local vars = { number=0 }
  function generate_number()
    local value = %vars.number
    %vars.number = value + 1
    return value

I think I've generated enough confusion for now. :-) Lua 5.0 is
supposed to have real lexical scoping, so there should be no need for
special treatment of upvalues anymore.

- Christian