0

If a closure is a stack frame that is

allocated when a function starts its execution, and not freed after the function returns (as if a 'stack frame' were allocated on the heap rather than the stack!),

doesn't that mean that the stack could get fragmented?

For instance, foo() is called, and then bar() is called. Both are closures. Is there any scenario that would make foo()'s closure to get out of scope, or to otherwise be candidate for deallocation (where deallocation in the case of the stack merely means that the runtime will move the stack pointer back, releasing space) while bar() continues to require space on the stack?

If such an event happens repeatedly, then the equivalent of heap fragmentation would occur on the stack, except that by the very nature of how stacks work, the space would be lost. Evidently this doesn't happen. What stops it from happening?

I'm interested specifically in the context of JavaScript, where one doesn't have even a rough idea of the machine running the code, but the question applies for any functional language.

In an effort to make the question down-to-earth...

Consider the following code sample.

outer = function() {
    var foo = function(v) {
        return function() { return v; }
    }

    var bar = function(w) {
        return function() { return w; }
    }

    var f = foo(5);
    var b = bar(7);
    document.writeln(f());
    document.writeln(b());
    document.writeln(f());
    document.writeln(b());
}
outer();

stack and heap

Sequence of events: outer() is called. Its return address is saved on the stack. foo, bar, f, and b are all hoisted, and hence are allocated on the stack as soon as outer() is called. foo() is called with parameter 5. The parameter to the function foo(), like any local variable, also gets allocated on the stack. The function foo() returns an anonymous function, also via the stack. The same pair of events occur for b and bar. I think that the anonymous function inside foo() is the closure because it refers to a variable in the scope that encloses it, but never mind the semantics and what is a closure. My question is: How do we know that f and foo() could not get dealloated while b and bar() are alive, hence creating an empty and inaccessible stack fragment?

Calaf
  • 10,113
  • 15
  • 57
  • 120
  • The quoted sentence is totally inaccurate. Don't believe it. – Bergi Jul 12 '17 at 22:36
  • This may be of help https://stackoverflow.com/questions/33802718/closures-and-es2015 – Ben Aston Jul 12 '17 at 22:40
  • Some JavaScript engines perform optimizations that can result in some variables being stored on the stack **if** it is safe to do so: https://stackoverflow.com/q/26150468/5217142 – traktor Jul 13 '17 at 00:07

1 Answers1

1

Ugh.

a closure is a stack frame …

No. A closure is a function that has a reference to the outer scope object it needs to look up variables.

a stack frame is allocated when a function starts its execution

Yes. The stack frame will (beside other things, like return addresses) contain a scope object with the declared variables. Or rather, a reference to it. Not all variables are allocated on the stack.

and not freed after the function returns

No. That's the whole point of the stack - when the function returns, the stack frame gets popped.

(as if a scope were allocated on the heap rather than the stack!)

Not sure why this says "as if". Scope objects that are referenced by closures are allocated on the heap.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I'm still very interested in understanding these details, but I am not yet in a position to evaluate whether what you wrote is correct (and I don't want to just bet that your high score implies you are right!). Can you cite any book that discusses what goes on the stack vs. what goes on the heap in Javascript in particular, or under functional programming in general? – Calaf Nov 14 '18 at 17:55
  • @Calaf I don't know or can recommend any books, I get my knowledge online usually. I could point you to [Wikipedia](https://en.wikipedia.org/wiki/Closure_(computer_programming)#Implementation_and_theory) where implementation strategies are discussed. Which one is actually used in your JS engine depends on the engine implementation, details about that are usually hard to come by unless there's a developer blog. – Bergi Nov 14 '18 at 19:07