Com S 641 meeting -*- Outline -*- * Scope (4.2) ** terms ------------------------------------------ SCOPE (4.2) begin var X: newint in !-----------------------! ! begin var Y: newint in! ! !------------------! ! ! ! X := 0; Y := X ! ! ! !------------------! ! ! end ! !-----------------------! end def: a declaration's *region* is an area of the program's text that within which def: a declaration's *scope* is that part of its region within which ------------------------------------------ - point out the regions, contours - show how to draw arrows from varrefs to formal declarations ... the declaration *may* have effect (varrefs may refer to it) ... the declaration *does* have effect (varrefs will refer to it) Formally, scopes are defined by defining what the free and bound variables are, for each piece of syntax. Hence the scope of I in begin define I = V in U end is U, less any regions in which I is redeclared within U Note: region and scope refer to declarations, not variables. however, sometimes people confuse the two, (ok when the same variable isn't used in 2 declarations, but can lead to confusion otherwise.) def: a hole in the scope is a region of a redefinition ** dynamic scoping ------------------------------------------ DYNAMIC SCOPING (4.2.1) A *dynamic binding* is extant References to a dynamically-bound name refer to the ------------------------------------------ ... during the evaluation of the body associated with the declaration or block ... most recent extant binding of that name. Q: What's the difference from static scoping? we use the run-time stack as the environment for running abstractions ------------------------------------------ EXAMPLES begin var A: newint; proc P = (A := 0) in begin fun A = true in call P end end ------------------------------------------ Show how the stack works with this... This shows that lots of things break when we use dynamic scoping: - copy rule / beta reduction fails (rename A to B...) - static type checking fails (can't check P statically...) ------------------------------------------ STATIC vs. DYNAMIC SCOPING (4.2.1) Dynamic scoping: [[invoke I]] e s = f e s where (I,f) \in e [[define I = U]]e s = ({(I,f)},s) where f e' s' = [[U]] e' s' -- OR -- [[invoke I]] e s = [[U]] e s where (I,U) \in e [[define I = U]]e s = ({(I,U)},s) Static scoping: [[invoke I]] e s = f s where (I,f) \in e [[define I = U]]e s = ({(I,f)},s) where f s' = [[U]] e s' ------------------------------------------ Recall how the environment is used as a stack. This really doesn't have much to do with block structure per se, it's more about semantics of abstractions... The second idea is sometimes named "call by text", and shows that dynamic scoping gives macro expansion. It's a naive copy rule that allows capture. If one wanted to discuss semantics of exception handlers, this would be the spot...