Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    Regular Coder
    Join Date
    Mar 2007
    Posts
    357
    Thanks
    46
    Thanked 22 Times in 21 Posts

    Unhappy Closures retaining values.

    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.)

    Code:
    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.

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    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:
    Code:
    Counter1 = ClosureFactory()
    Counter2 = ClosureFactory()
    
    Counter1()
    Counter1()
    
    Counter2()
    Counter2()
    
    > 1
    > 2
    > 1 
    > 2
    Trinithis

  • Users who have thanked Trinithis for this post:

    flynch01 (10-10-2008)

  • #3
    Regular Coder
    Join Date
    Mar 2007
    Posts
    357
    Thanks
    46
    Thanked 22 Times in 21 Posts
    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.

  • #4
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    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.)

  • #5
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    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.
    Last edited by liorean; 10-17-2008 at 12:19 PM.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •