Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6697179
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T06:25:46+00:00 2026-05-26T06:25:46+00:00

I have a question about how closures are implemented. Say this is in a

  • 0

I have a question about how closures are implemented.

Say this is in a file named test.lua:

local a = 'asdf'

local function b()
    return a
end

a = 10

return b

And another file does

a = require 'test'
a()

it will print

10

If a is a pointer on the stack to 'asdf' (on the heap I assume, but it doesn’t matter), and the closure b is created so presumably the address that was in a is saved for b to use, how does a = 10 change the pointer inside the closure as well?

Wikipedia says quite well what is perplexing me:

A language implementation cannot easily support full closures if its run-time memory model allocates all local variables on a linear stack1. In such languages, a function’s local variables are deallocated when the function returns.

I was thinking that perhaps b really didn’t save a pointer to 'asdf' but a stack offset to a, so that you can change a and the stack offset will get you to a which points to the last thing you set a to, but then how does this work when a (the pointer) is popped off the stack and the stack offset becomes invalid?

1 I know Lua doesn’t allocate the values on the stack, but it allocates local pointers on the stack to values in the heap, doesn’t it?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T06:25:46+00:00Added an answer on May 26, 2026 at 6:25 am

    I really wish you had named these variables a bit more reasonably. So I will:

    local inner = 'asdf'
    
    local function b()
        return inner
    end
    
    inner = 10
    
    return b
    

    and

    func = require 'test'
    func()
    

    OK, now that we know what we’re talking about, I can proceed.

    The Lua chunk test has a local variable called inner. Within that chunk you create a new function b. Since this is a new function, it has a scope within the scope of the chunk test.

    Since it is within a function, it has the right to access local variables declared outside of that function. But because it is inside of a function, it does not access those variables like it would one of its own locals. The compiler detects that inner is a local variable declared outside of the function’s scope, so it converts it into what Lua calls an “upvalue”.

    Functions in Lua can have an arbitrary number of values (up to 255) associated with them, called “upvalues”. Functions created in C/C++ can store some number of upvalues by using lua_pushcclosure. Functions created by the Lua compiler use upvalues to provide lexical scoping.

    A scope is everything that happens within a fixed block of Lua code. So:

    if(...) then
      --yes
    else
      --no
    end
    

    The yes block has a scope, and the no block has a different scope. Any local variables declared in the yes block cannot be accessed from the no block, because they are outside of the scope of the no block.

    The Lua constructs that define a scope are if/then/else/end, while/do/end, repeat/until, do/end, for/end, and function/end. Also, each script, called a Lua “chunk”, has a scope.

    Scopes are nested. From within one scope, you can access local variables declared in a higher scope.

    A “stack” represents all variables declared as local within a particular scope. So if you have no local variables in a certain scope, the stack for that scope is empty.

    In C and C++, the “stack” that you are familiar with is just a pointer. When you call a function, the compiler has predetermined how many bytes of space that the function’s stack needs. It advances the pointer by that amount. All stack variables used in the function are just byte offsets from the stack pointer. When the function exits, the stack pointer is decreased by the stack amount.

    In Lua, things are different. The stack for a particular scope is an object, not merely a pointer. For any particular scope, there are some number of local variables defined for it. When the Lua interpreter enters a scope, it “allocates” a stack of the size necessary to access those local variables. All references to local variables are just offsets into that stack. Access to local variables from higher scopes (previously defined) simply access a different stack object.

    So in Lua, you conceptually have a stack of stacks (which I will refer to as the “s-stack” for clarity). Each scope creates a new stack and pushes it, and when you leave a scope, it pops the stack off of the s-stack.

    When the Lua compiler encounters a reference to a local variable, it converts that reference into an index into the s-stack, and an offset into that particular stack. So if it accesses a variable in the current local stack, the index into the s-stack refers to the top of the s-stack, and the offset is the offset into that stack where the variable is.

    That’s fine for most Lua constructs that access scopes. But function/end don’t just create a new scope; they create a new function. And this function is allowed to access stacks that aren’t just the local stack of that function.

    Stacks are objects. And in Lua, objects are subject to garbage collection. When the interpreter enters a scope, it allocates a stack object and pushes it. So long as the stack object is pushed onto the s-stack, it cannot be destroyed. The stack of stacks refers to the object. However, once the interpreter exits the scope, it pops the stack off of the s-stack. So since it is no longer referenced, it is subject to being collected.

    However, a function that accesses variables outside of its own local scope can still be referencing that stack. When the Lua compiler sees a reference to a local variable that is not within the function’s local scope, it alters the function. It figures out which stack the local it is referencing belongs to, and then stores that stack as an upvalue in the function. It converts the reference to that variable to an offset into that particular upvalue, rather than an offset into a stack that is currently on the s-stack.

    So as long as the function object continues to exist, so too will the stack(s) that it references.

    Remember that stacks are dynamically created and destroyed as the Lua interpreter enters and exits the scope of functions. So if you were to run test twice, by calling loadfile and executing the returned function twice, you would get two separate functions that refer to two separate stacks. Neither function will see the value from the other.

    Note that this may not be exactly how it’s implemented, but that’s the general idea behind it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i have question about finding maximum x or y-value in text file. This is
I have a question about locking. This doesn't have to be only about record
I have a question about using new[] . Imagine this: Object.SomeProperty = new[] {string1,
i have question about why should we use return in get,if dont use what
Today I have question about Eclipse . I use this IDE very long and
I have a question about this script I found and used. It works but
I have a question about javascript's protected memory. If I have a function done
https://stackoverflow.com/a/64983/468251 - Hello, I have question about this code, how made that working with
I have question about NSView: Imagine a Custom View where the mouseDown, mouseDrag and
I have question about normalization. Suppose I have an applications dealing with songs. First

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.