5 ms·
Interesting ... Not sure how many languages other than Pascal support local functions and allow access to (potentially multiple levels of) parent variables in t
by HarHarVeryFunny 3y ago
Interesting ... Not sure how many languages other than Pascal support local functions and allow access to (potentially multiple levels of) parent variables in this way. The normal Pascal terminology for this "array of frame pointers" is the "display", and it wouldn't normally be copied during a function/procedure entry - just updated (assuming the function being entered had local functions that accessed parent variables).
- whoopdedo 3y agoOnly most of the languages you use every day[1]. Pascal inherited nested functions from ALGOL so everything in that family does it. Lisp dialects with lexical scope will have it. You can even get it in C if you use GCC[2]. (And if you don't mind turning off the NX stack.) [1] https://en.wikipedia.org/wiki/Nested_function#Languages https://en.wikipedia.org/wiki/Nested_function#Languages [2] https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Nested-Functions.html https://www.gnu.org/software/c-intro-and-ref/manual/html_nod...
- HarHarVeryFunny 3y agoWell, I'm not actually using ALGOL or Lisp every day, but ok ... :) There's a variety of implementations there though - some seem to be talking about closures, and at least one (Rust) doesn't appear to support parent variable access.
- wmil 3y agoJavaScript seems like the obvious one. Isn't this just a lexical closure? It's common in scripting languages. https://wiki.c2.com/?LexicalClosure https://wiki.c2.com/?LexicalClosure
- HarHarVeryFunny 3y agoI don't know how compilers typically implement closures, but that does seem to be what some languages on that list (e.g. D) support by way of "nested/local functions", and is obviously a bit different in terms of variable lifetime. In Pascal local functions are not closures and do not affect variable storage. All variables are still stored in the stack frame (unless optimized to be in registers), and local functions can access their parent's (& grandparent's etc) variables via pointers to their stack frames, which are normally held globally in an array of frame pointers called the display. For a Pascal depth-N nested local function to access it's parent's variables it would use the depth-(N-1) display entry, for it's grandparent's variables the depth-(N-2) entry etc. When a parent calls a nested function the only thing that needs to change in the display is to set the depth N-1 display pointer to it's own stack frame, and to replace it with the old N-1 pointer when the call is complete. The grandparent/etc entries don't need to change. This x86 ENTER instruction appears to be designed for a more general case than Pascal, since it's apparently copying the entire display (array of frame pointers), not just doing the more efficient incremental update/restore that is all Pascal needs. It's interesting to see Raymond Chen writing about this "almost always unused" ENTER parameter since it suggests that compilers are not using it even for those languages that might seem to be able to make use of it. Perhaps, as for Pascal, it's not the most efficient way, or perhaps just because languages such as JavaScript don't normally compile to machine code.