...

View Full Version : Closures retaining values.



flynch01
10-10-2008, 05:58 PM
I've been playing around with Lua. And recently in a JS issue I had I was shown how to fix it with Closures. I understood why, but. I don't understand the why behind the why. That probably makes no sense so, here's the Lua example of what I'm trying to do.

(It should be obvious what this does, whether you know Lua or not.)



function ClosureFactory ()
UpperValue = 0
return function ()
UpperValue = UpperValue + 1
return UpperValue
end
end

ClosureFactory()
ClosureFactory()


The two function calls output:

> 1
> 2

I understand how closures can access their outer context where they were created. And I understand that they maintain the value throughout continuous function calls. But what I don't understand. Is why they maintain the value. Surely once the ClosureFactory() is called, it resets the UpperValue to 0. So the newly created closure is accessing 0 again. I've looked everywhere, at Closures in general, wikipedia, functors in C, closures in JS in Lua and Python equivalents. No where explains the theory or why the value is maintained.

The best answer I came up with is that once the closure is returned, the closure is what is called from then on, never the factory. But that clashes with the idea that the factory produces a new closure each call.

Trinithis
10-10-2008, 06:49 PM
I'm familiar with closures, and your example seems wrong. It should have not printed numeric values . . . it should have printed function values if anything (and maybe that's what it did do).

I don't know Lua, but this is what I think should have happened:


Counter1 = ClosureFactory()
Counter2 = ClosureFactory()

Counter1()
Counter1()

Counter2()
Counter2()

> 1
> 2
> 1
> 2

flynch01
10-10-2008, 07:51 PM
Yeah I forgot to put any print or echo methods in it. The idea was the same though. It was just the theory I was looking for. Which... you just answered. You put the result of the factory inside the new variable. Which I wasn't doing. Which makes a LOT more sense to me now.

Thanks.

jkd
10-17-2008, 07:35 AM
The idea is scope. Every time ClosureFactory() is called, it creates a new local scope, which UpperValue is initialized to be part of. Since the return value is a function that was created within the same scope, it has access to all of the scope's variables. Just because the ClosureFactory() call terminates doesn't mean the scope is destroyed either (especially since the return value has references within it).

I'm sure liorean will come by and give a more correct explanation, but that is how I understand. (If you have ever worked with Scheme, it is very similar, except Scheme uses static binding in the scope rather than dynamic.)

liorean
10-17-2008, 08:24 AM
I don't think I really have to explain it, you did a pretty good job there.

But explaining it as I see it despite that, basically the way it works is:

The call to ClosureFactory creates a new scope, let's call it CF1. In CF1 there is a variable UpperValue. It returns an anonymous function, let's call it Closure1, that has the CF1 scope in it's scope chain. When this Closure1 function is called it will increment the value of the UpperValue variable in the CF1 scope and return the new value.

The next call to ClosureFactory will create a new scope CF2 which contains a variable UpperValue. It returns Closure2 that has CF2 in it's scope chain. When Closure2 is called it will increment the value or the UpperValue variable in the CF2 scope and return the new value.

Closure1 is thus updating a different UpperValue than Closure2 is. The CF1 UpperValue variable is different to the CF2 Uppervalue variable.



The idea of closures is basically this - a closure is a function that remembers which scopes are in its scope chain based on the call stack at the time they were created. Each call to the closure creating function will create a different scope. And as long as the closure remains, all the scopes it has access to are kept alive so that the closure can access the variables that were visible in their scope chain at the creation time.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum