Tuesday, February 27, 2007

Closure - 3

Wow, I finally got the concept of closure. I got it from reading Wikipedia - Scope (Programming)

Suppose you have this piece of code:

x = 0

do
  local x = 0
  function f () return x end
  function g () x = x + 1; return f() end
end

print(x)    -- 0
print(f() ) -- 0
print(g() ) -- 1
print(x)    -- 0

x = 5
print(x)    -- 5
print(f() ) -- 1
print(g() ) -- 2
print(x)    -- 5

The first occurrence of x is a global variable, which is dynamic; it can be changed by an assignment anywhere else in the program.

However, the second occurrence of x is something completely different. It is inside a do ... end construct (a chunk in Lua jargon), and it is defined local in that chunk. It cannot be accessed outside this chuck. Nevertheless, through the functions f and g the value of the x inside the do ... end construct can be accessed. It can be looked up in the script code, and, therefore, can be called a "lexical variable", because the scope of the variable is lexical (determined by executable code--functions--in the script). Remember, the functions f and g can be accessed outside the do ... end construct, because they are defined as global.

So a closure is a global function and its "lexical variables" (upvalues in Lua jargon), i.e. variables that can only be accessed through the function of the closure.

Now, suppose you had used a global variable x inside the do ... end construct:

x = 0

do
  x = 0
  function f () return x end
  function g () x = x + 1; return f() end
end

print(x)    -- 0
print(f() ) -- 0
print(g() ) -- 1
print(x)    -- 1

x = 5
print(x)    -- 5
print(f() ) -- 5
print(g() ) -- 6
print(x)    -- 6

Now there is only one and the same variable x, and there is no upvalue in this piece of code. Therefore, neither f nor g are closures.

No comments: