1 / 49

II. Frames and frame structures

II. Frames and frame structures Frame – set of bindings generated together in a binding generation event (frame ~ mini environment ) When an event generates frame F , then the new environment is (for some E ) E itself was similarly generated

mirra
Download Presentation

II. Frames and frame structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. II. Frames and frame structures • Frame – set of bindings generated together in a binding generation event (frame ~ minienvironment ) • When an event generates frame F, then the new environment is (for some E) • E itself was similarly generated • In the future, E may become again the current environment • Frames are added/removed in LIFO A stack discipline environment

  2. Environment structure --- past and present frames -- a tree: each path from root is a stack of frames • Activation start(binding generation event) • generation of frame • implemented as push (onto current environment) • Look-up --- search in frame stack, top-to-bottom • Activation exit -- restoration of previous environment • Frame disposed of(automatically/garbage collection) --- pop Let us re-visit previous example environment

  3. Example: (start with empty environment) Activationdirectly evaluatedframe The value 7 is returned, down to to act0 environment

  4. Dynamic scoping Results of resolutions depend on how environments are modified when a activation is entered Option A: new generated bindings are always merged into current environment (at point of entrance) dynamic scoping • Simple, elegant approach • Works well with stack-based implementations of pl’s We discuss implementation, present examples , show that approach is WRONG environment

  5. environment

  6. Activation and frame stacks are in 1-1 correspondence! • Each activation A --- associated frame F(A) generated & removed together • Look-up when A is current (top of activation stack) starts at F(A) (then top of frame stack) then (if needed) goes down Wlog: going down uses the dynamic parent to reach the activation below, then its frame Look-up follows the dynamic parents chain, until a binding is found (or fail announced) environment

  7. Example revisited (let* x =3, f = ….) Act framed-evalexp evaluatedexp The result 7 is returned from #3 to #2 to #1 to #0 Q: What would happen if the body of f contained f? environment

  8. Example: We start from g(3), after the bindings of the let* were established, showing successive (partial)stacks,(‘control’ shown with a circle) ) Here, f, y are d-evaluated environment

  9. When returns with 4, we are back at act(g) Now, d-eval f, y+1 Finally, back in act(g), 4+5 evaluates 9, and the computation of the let* returns this value environment

  10. Example: Evaluate See details of stack evolution next page environment

  11. Act frame eval d-eval The final result, 10, moves down to #0 environment

  12. Example: next page environment

  13. Act frame eval d-eval Wrong! The final result is 9 environment

  14. The source of the problem: A delay between • creation of a function value(from a functionexpression) • its application  The bindings for its free variables available when it is applied may differ from those when it is created environment

  15. Act framed-eval #2 and the binding x1 are gone! #3 is ontop of#1 Free variable: x(or worse, could be defined) environment

  16. The source of the problem: A delay between • creation of a function value(from a functionexpression) • its application  The bindings for its free variables available when it is applied may differ from those when it is created environment

  17. What is the result? Right or wrong? environment

  18. What happens after a call E(2)? environment

  19. Can such phenomena also happen in C? environment

  20. In dynamic scoping the free (global) variables in a function body are associated with bindings late: when resolution is performed The associations use the stack of frames, accessed in order of generation This allows interference!  no relationship to static structure Static structure is nota reliable predictor of execution environment

  21. Various problems of dynamic scoping: • Same calls of a function (with same arg value) may return different results (including error msgs in some) (lack of referential transparency) • Change of a formal parameter of a function may cause others to change their behavior • A function called by F may `see’ F’s parameters and locals– a breach of abstraction/security • Useless to perform static checks such as • Static type-check • Is a variable defined before being used? (free var check) unpredictable behavior, often unrelated to static structure environment

  22. Manifestation of problems does not require • Higher-order functions • Recursion (Although it is more common when these are present) Conclusion: dynamic scoping is Simple, elegant, (quite) efficient,but wrong! now considered an error, not used in modern pl’s Recall: Results of resolutions depend on how environments are modified when a activation is entered What other options are there ? environment

  23. Static scoping The problem (in dynamic): A delay between creation of a function value andits application • The bindings for its free variables available when it is applied are different from those when it is created The solution: • When a function value is created, the bindings for its free variables (from current environment) are attached to it • When it is applied, these bindings are used as base environment environment

  24. A function value (static scoping): fv= <p;b;E> , where • p is the parameter(s) • b is the body • E is an environment with bindings for The triple <p;b,E>is called a (function) closure • Intended to be used later in various places (delayed evaluation) • A closed package that contains everything needed for its future evaluation(s) environment

  25. Closure and environment creation: • When a function expression is evaluated in environment E, the value<pars;b,E’>is created E’ is derived from E • When a function value <pars;b,E’> is applied to args in environment E’’ • a frame F of bindings parsargs is generated • the activation executes in environment • When it terminates, the environment E’’ is restored The environment component of a function value is derived from that of its time &place of creation environment

  26. Note: environment creation upon entrance to let, let* is unchanged For letrec --- below environment

  27. Implementation of Environment creation: (in all implementations, the term function closure is used) • Fully computed at the time of creation: • The environment component of a function value is computed (when it is created)by copying the relevantbindings from the current environment: if E is current environment, • That of an activation is computed (before it starts) A common choice in implementations of functional pl’s environment

  28. Using frames linked by references: (A common approach for imperative pl’s) • An environment is a (linked) list of frames, viewed as a stack: • An entry: a frame & a reference to the next entry [F1,&F2] [F2, &F3] ….. • The first entry in the list is the top of the stack The reference in an entry is its static parent or static pointer environment

  29. An activation contain a reference to the top/first entry of its environment and a dynamic parent/pointer, to the next entry on the activation stack The dynamic and static parents, from an activation and its environment, maylead to unrelated activation and environment! activations environments env(a8) = f8, f4, f1, … f11 a8 f8 f4 f1 a1 environment

  30. A function value: <p;b;&F> , where &F is a reference to a frame --- the top frame of the current environment at its time of creation The triple <p;b;&F> is also called afunction closure (note: it may contain extra bindings!) 4. implemented as push --- create an entry < F,&top(E)>, make it the new top (this reference is the static parent of F) Previous examples revisited: environment

  31. act frame dynamic: static: A2 A1 A5 x+y A4 f, x+5 • A3 g, 2 Result: 10 passed down to A4, … A0 A0 3 [F0:{}; nill] environment

  32. A0 A4 x+y A3 g, 3 A2 is now gone from stack Frame lives! A2 A1 f, 1 environment

  33. A2 A1 A5 x+y Result 10 to A4 to A3; what next? A4 f, x+5 A3 g, 2 A0 3 [F0{}; nill] environment

  34. Observations: • Assume (A;F) are current staticparent(F), dynamic parent(A) are not necessarily associated with each other • Whenanactivation dies, the frames of its associated environment may be referenced from liveactivations or function values  1. An activation popped from stack is gone (dead); its associated frame (often) lives on(where?) 2. Static parent may correspond to no live activation! (is that a problem?) environment

  35. The environment structure is a tree (how do we know it is a tree, not a graph? ) • Current environment is a path from a node to the root • When an activation starts, a node is added to the tree, as a child of some existing node (& becomes top of current environment) • When an activation terminates, a different path becomes the current environment Nodes are removed from the tree only by garbage collection (when provably they are not referenced from any live entity) no explicit pop environment

  36. Other kinds of blocks: Afunction value is a package, carrying its own environment, since it moves around and may be invoked in various places Aregular block (let, let*, letrec)has no need of such a mechanism • Upon entrance to new region, new bindings are added to current environment (static parent ~ dynamic parent!) • Upon exit, previous environment is restored let and let* are simple, letrec requires re-consideration environment

  37. Rules for let: (entered in current environment E) • Evaluate defining expressions in current environment • Create the frame F for the defined variables • Evaluate the body (~ activation) in • Upon exit, restore E reflects the scope rule of let, the fact that it is not recursive What are the rules for let*? environment

  38. For a letrec, the defining expressions need to be evaluated in the new environment!  Assume is evaluated in environment E But, this solution does not work now! environment

  39. The solution: Do the evaluation of the functions and the construction of the new environment in one step The requirement: After this step environment

  40. A solution with assignable cells: (the Scheme implementation) What is the role of delayed evaluation here? Can you think of a purely functional solution? environment

  41. Assume computation starts from activation A0, and frame [F0:{};nill] How will the activation stack and the environment structure evolve? Note: The final value true is returned from final activation #i to #i-1, … to #0. Those in middle just pass it on environment

  42. The rules: environment

  43. For letrec: environment

  44. Comments: • How does a computation start? A zero’th activation, with initial environment which may be empty, or not (depending on pl/implementation) • The model as described can explain activations and binding management in most languages, including interactive mode in functional languages however, the global environment and define in Scheme behave differently (still based on environments) environment

  45. Functions in a pl exist on three levels: • L1: Function expressions (static) • L2: functionvalues (dynamic) • L3: activations of function values (dynamic) The relationships L1L2 , L2L3 are 1-m: • Many values may be created from an expression • Many activations of a value may occur, even be live simultaneously The distinction between L1, L2 is not evident in substitution model and in dynamic scope environment

  46. Is behavior under static scoping compatible with static structure? Denote: • For a use u(x) in program: declu(u(x)) – the declaration d(x) that statically binds it (static) • For a binding b generated at run-time for a declaration d(x) : declb(b)=d(x) (dynamic) • For a use u(x) : resol(u(x)) – the binding returned by resolving it in current environment (dynamic) Claim1: declb(resol(u(x)))= declu(u(x)) environment

  47. Meaning of arrows: resolves to static binding generated for xv1 d(x) xv2 d(x) xv3 xv4 u(x) u(x) environment

  48. Can prove a stronger statement: If a binding xv is generated for declaration of x for a new activation, Then for every use of x in the scope of this declaration, its resolution always returns v let f = let x = 3 in lambda y.x+y;; …. f 5 returns 8 (always) Static structure is a reliable predictor of execution environment

  49. Static scope avoids the problems of dynamic scope: • Calls of a function with same arguments behave the same – referential transparency holds • Change of formal parameter of a function does not change behavior (in activations of other functions) -- no surprises • function is a black box – no external function may observe values of locals • Useful to perform static check: • that a use is in scope of a declaration guarantees: resolution never returns unbound variable • Static type-checking guarantees absence of run-time type errors environment

More Related