file no11

Lexical Scope and Block Structure

#drnsecscope#24858> The introduction of <#64760#><#24859#>local<#24859#><#64760#> requires some additional terminology concerning the syntax of Scheme and the structure of functions. Specifically, we need words to discuss the usage of names, <#24860#>e.g.<#24860#>, variables, function names, and structure names. For a simple example, consider the following two definitions:
<#24865#>(define<#24865#> <#24866#>(f<#24866#> <#72339#>#tex2html_wrap_inline73164#<#72339#><#24868#>)<#24868#> <#24869#>(+<#24869#> <#24870#>(*<#24870#> <#72340#>#tex2html_wrap_inline73166#<#72340#> <#72341#>#tex2html_wrap_inline73168#<#72341#><#24873#>)<#24873#> <#24874#>25))<#24874#>
<#24875#>(define<#24875#> <#24876#>(g<#24876#> <#24877#>x)<#24877#> <#24878#>(*<#24878#> <#24879#>12<#24879#> <#24880#>(expt<#24880#> <#24881#>x<#24881#> <#24882#>5)))<#24882#> 
Clearly, the underlined occurrences of <#64764#><#24886#>x<#24886#><#64764#> in <#64765#><#24887#>f<#24887#><#64765#> are completely unrelated to the occurrences of <#64766#><#24888#>x<#24888#><#64766#> in <#64767#><#24889#>g<#24889#><#64767#>. As mentioned before, if we systematically replaced the underlined occurrences with <#64768#><#24890#>y<#24890#><#64768#>, the function would still compute the exact same numbers. In short, the underlined occurrences of <#64769#><#24891#>x<#24891#><#64769#> only mean something in the definition of <#64770#><#24892#>f<#24892#><#64770#> and nowhere else. At the same time, the first occurrence of <#64771#><#24893#>x<#24893#><#64771#> is different from the others. When we apply <#64772#><#24894#>f<#24894#><#64772#> to a number <#64773#><#24895#>n<#24895#><#64773#>, this occurrence completely disappears; in contrast, the others are replaced with <#64774#><#24896#>n<#24896#><#64774#>. To distinguish these two forms of variable occurrences, we call the one to the right of the <#64775#><#24897#>BINDING<#24897#><#64775#> occurrence of <#64776#><#24898#>x<#24898#><#64776#> and those in the body the <#64777#><#24899#>BOUND<#24899#><#64777#> occurrences. We also say that the binding occurrence of <#64778#><#24900#>x<#24900#><#64778#> binds all occurrences of <#64779#><#24901#>x<#24901#><#64779#> in the body of <#64780#><#24902#>f<#24902#><#64780#>, and from the discussion above, the body of <#64781#><#24903#>f<#24903#><#64781#> is clearly the only textual region of the function where the underlined binding occurrence of <#64782#><#24904#>x<#24904#><#64782#> can bind other occurrences. The name of this region is <#64783#><#24905#>x<#24905#><#64783#>'s <#64784#><#24906#>LEXICAL SCOPE<#24906#><#64784#>. We also say that the definitions of <#64785#><#24907#>f<#24907#><#64785#> and <#64786#><#24908#>g<#24908#><#64786#> (or other definitions in the <#24909#>Definitions<#24909#> window) have <#64787#><#24910#>GLOBAL SCOPE<#24910#><#64787#>. The description of an application of <#64788#><#24911#>f<#24911#><#64788#> to a number <#64789#><#24912#>n<#24912#><#64789#> suggests the following pictorial representation of the definition:

#picture24914#

The bullet over the first occurrence indicates that it is a binding occurrence. The arrow that originates from the bullet suggests the flow of values. That is, when the value of a binding occurrence becomes known, the bound occurrences receive their values from there. Put differently, when we know the binding occurrence of a variable occurrence, we know where the value will come from during an evaluation. Along similar lines, the scope of a variable also dictates where we can rename it. If we wish to rename a parameter, say, from <#64796#><#24930#>x<#24930#><#64796#> to <#64797#><#24931#>y<#24931#><#64797#>, we search for all bound occurrences in the scope of the parameter and replace them with <#64798#><#24932#>y<#24932#><#64798#>. For example, if the function definition is the one from above:

<#24937#>(define<#24937#> <#24938#>(f<#24938#> <#24939#>x)<#24939#> <#24940#>(+<#24940#> <#24941#>(*<#24941#> <#24942#>x<#24942#> <#24943#>x)<#24943#> <#24944#>25))<#24944#>
renaming <#64799#><#24948#>x<#24948#><#64799#> to <#64800#><#24949#>y<#24949#><#64800#> affects two bound occurrences:
<#24954#>(define<#24954#> <#24955#>(f<#24955#> <#24956#>y)<#24956#> <#24957#>(+<#24957#> <#24958#>(*<#24958#> <#24959#>y<#24959#> <#24960#>y)<#24960#> <#24961#>25))<#24961#>
No other occurrences of <#64801#><#24965#>x<#24965#><#64801#> outside of the definitions need to be changed. Obviously function definitions also introduce a binding occurrence for the function name. If a definition introduces a function named <#64802#><#24966#>f<#24966#><#64802#>, the scope of <#64803#><#24967#>f<#24967#><#64803#> is the entire sequence of definitions:

#picture24969#

That is, the scope of <#64816#><#25008#>f<#25008#><#64816#> includes all definitions above and below the definition of <#64817#><#25009#>f<#25009#><#64817#>.
<#25012#>Exercise 18.2.1<#25012#> Here is a simple Scheme program:

<#25018#>(d<#25018#><#25019#>efine<#25019#> <#25020#>(p1<#25020#> <#25021#>x<#25021#> <#25022#>y)<#25022#> 
  <#25023#>(+<#25023#> <#25024#>(*<#25024#> <#25025#>x<#25025#> <#25026#>y)<#25026#> 
     <#25027#>(+<#25027#> <#25028#>(*<#25028#> <#25029#>2<#25029#> <#25030#>x)<#25030#> 
        <#25031#>(+<#25031#> <#25032#>(*<#25032#> <#25033#>2<#25033#> <#25034#>y)<#25034#> <#25035#>22))))<#25035#> 
<#25036#>(d<#25036#><#25037#>efine<#25037#> <#25038#>(p2<#25038#> <#25039#>x)<#25039#> 
  <#25040#>(+<#25040#> <#25041#>(*<#25041#> <#25042#>55<#25042#> <#25043#>x)<#25043#> <#25044#>(+<#25044#> <#25045#>x<#25045#> <#25046#>11)))<#25046#> 
<#25047#>(d<#25047#><#25048#>efine<#25048#> <#25049#>(p3<#25049#> <#25050#>x)<#25050#> 
  <#25051#>(+<#25051#> <#25052#>(p1<#25052#> <#25053#>x<#25053#> <#25054#>0)<#25054#> 
     <#25055#>(+<#25055#> <#25056#>(p1<#25056#> <#25057#>x<#25057#> <#25058#>1)<#25058#> <#25059#>(p2<#25059#> <#25060#>x))))<#25060#> 
Draw arrows from <#64818#><#25064#>p1<#25064#><#64818#>'s <#64819#><#25065#>x<#25065#><#64819#> parameter to all its bound occurrences. Draw arrows from <#64820#><#25066#>p1<#25066#><#64820#> to all bound occurrences of <#64821#><#25067#>p1<#25067#><#64821#>. Copy the function and rename the parameter <#64822#><#25068#>x<#25068#><#64822#> of <#64823#><#25069#>p1<#25069#><#64823#> to <#64824#><#25070#>a<#25070#><#64824#> and the parameter <#64825#><#25071#>x<#25071#><#64825#> of <#64826#><#25072#>p3<#25072#><#64826#> to <#64827#><#25073#>b<#25073#><#64827#>. Check the results with DrScheme's <#25074#>Check Syntax<#25074#> button.~ external Solution<#64828#><#64828#>
In contrast to top-level function definitions, the scope of the definitions in a <#64829#><#25082#>local<#25082#><#64829#> are limited. Specifically, the scope of local definitions <#25083#>is<#25083#> the <#64830#><#25084#>local<#25084#>-expression<#64830#>. Consider the definition of an auxiliary function <#64831#><#25085#>f<#25085#><#64831#> in a <#64832#><#25086#>local<#25086#>-expression<#64832#>. It binds all occurrences within the <#64833#><#25087#>local<#25087#>-expression<#64833#> but none that occur outside:

#picture25089#

The two occurrences outside of <#64851#><#25136#>local<#25136#><#64851#> are not bound by the local definition of <#64852#><#25137#>f<#25137#><#64852#>. As always, the parameters of a function definition, local or not, is only bound in the function's body and nowhere else:

#picture25139#

1=<#64861#>

<#25164#>(l<#25164#><#25165#>ocal<#25165#> <#25166#>(<#25166#><#25167#>(define<#25167#> <#25168#>(f<#25168#> <#25169#>x)<#25169#> <#25170#>(+<#25170#> <#25171#>(*<#25171#> <#25172#>x<#25172#> <#25173#>x)<#25173#> <#25174#>55))<#25174#>
        <#25175#>(define<#25175#> <#25176#>(g<#25176#> <#25177#>y)<#25177#> <#25178#>(+<#25178#> <#25179#>(f<#25179#> <#25180#>y)<#25180#> <#25181#>10)))<#25181#> 
  <#25182#>(f<#25182#> <#25183#>z))<#25183#> 
<#64861#> <#25186#><#25186#><#25187#><#25187#><#64862#>#tex2html_wrap73172#<#64862#> 2=<#64863#>
<#25192#>(+<#25192#> <#25193#>(*<#25193#> <#25194#>2<#25194#> <#25195#>x)<#25195#> <#25196#>10)<#25196#>
<#64863#> <#25199#><#25199#><#25200#><#25200#><#64864#>#tex2html_wrap73174#<#64864#> Since the scope of a function name or a function parameter is a textual region, people often draw a box to indicate some scope. More precisely, for parameters a box is drawn around the body of a function:
<#25206#>(d<#25206#><#25207#>efine<#25207#> <#25208#>(f<#25208#> <#25209#>x)<#25209#>
  <#25211#>)<#25211#> 
In the case of a local definition, the box surrounds the entire local expression:
<#25219#>(d<#25219#><#25220#>efine<#25220#> <#25221#>(h<#25221#> <#25222#>z)<#25222#>
   <#25224#>)<#25224#> 
In this example, the box describes the scope of the definitions of <#64865#><#25228#>f<#25228#><#64865#> and <#64866#><#25229#>g<#25229#><#64866#>. 3=<#64867#>
<#25233#>(l<#25233#><#25234#>ocal<#25234#> <#25235#>(<#25235#><#25236#>(define<#25236#> <#25237#>(f<#25237#> <#25238#>x<#25238#> <#25239#>y)<#25239#> <#25240#>(+<#25240#> <#25241#>(*<#25241#> <#25242#>x<#25242#> <#25243#>y)<#25243#> <#25244#>(+<#25244#> <#25245#>x<#25245#> <#25246#>y)))<#25246#>
        <#25247#>(d<#25247#><#25248#>efine<#25248#> <#25249#>(g<#25249#> <#25250#>z)<#25250#> 
           <#25252#>)<#25252#> 
        <#25253#>(define<#25253#> <#25254#>(h<#25254#> <#25255#>x)<#25255#> <#25256#>(f<#25256#> <#25257#>x<#25257#> <#25258#>(g<#25258#> <#25259#>x))))<#25259#> 
  <#25260#>(h<#25260#> <#25261#>y))<#25261#> 
<#64867#> <#25264#><#25264#><#25265#><#25265#><#64868#>#tex2html_wrap73176#<#64868#> Using a box for a scope, we can also easily understand what it means to re-use the name of function inside of a <#64869#><#25267#>local<#25267#>-expression<#64869#>:
<#25272#>(d<#25272#><#25273#>efine<#25273#> <#25274#>(a-function<#25274#> <#25275#>y)<#25275#>
   <#25277#>)<#25277#>