【文章內(nèi)容簡介】
location, called its Lvalue – Identifier on right refers to contents, called Rvalue ?ML reference cells and assignment ? Different types for location and contents x : int nonassignable integer value y : int ref location whose contents must be integer !y the contents of cell y ref x expression creating new cell initialized to x ? ML form of assignment y := x+3 place value of x+3 in location (cell) y y := !y + 3 add 3 to contents of y and store in location y ML examples ?Create cell and change contents val x = ref “Bob”。 x := “Bill”。 ?Create cell and increment val y = ref 0。 y := !y + 1。 ?While loop val i = ref 0。 while !i 10 do i := !i +1。 !i。 Bob Bill x 1 0y Parameter passing ?Passbyreference ? Caller places Lvalue (address) of actual parameter in activation record ? Function can assign to variable that is passed ?Passbyvalue ? Caller places Rvalue (contents) of actual parameter in activation record ? Function cannot change value of caller’s variable ? Reduces aliasing (alias: two names refer to same loc) Example function f (x) = { x := x+1。 return x }。 var y : int = 0。 print f(y)+y。 fun f (x : int ref) = ( x := !x+1。 !x )。 y = ref 0 : int ref。 f(y) + !y。 fun f (z : int) = let x = ref z in x := !x+1。 !x end。 y = ref 0 : int ref。 f(!y) + !y。 pseudocode Standard ML Access to global variables ?Two possible scoping conventions ? Static scope: refer to closest enclosing block ? Dynamic scope: most recent activation record on stack ?Example int x=1。 function g(z) = x+z。 function f(y) = { int x = y+1。 return g(y*x) }。 f(3)。 x 1 x 4 y 3 z 12 outer block f(3) g(12) Which x is used for expression x+z ? Activation record for static scope ?Control link ? Link to activation record of previous (calling) block ?Access link ? Link to activation record of closest enclosing block in program text ?Difference ? Control link depends on dynamic behavior of prog ? Access link depends on static form of program text Control link Local variables Intermediate results Environment Pointer Parameters Return address Return result addr Access link Complex nesting structure int x=1。 function g(z) = x+z。 function f(y) = { int x = y+1。 return g(y*x) }。 f(3)。 function m(…) { int x=1。 … function n( … ){ function g(z) = x+z。 … { … function f(y) { int x = y+1。 return g(y*x) }。 … f(3)。 … } … n( … ) …} … m(…) Simplify to Simplified code has same block nesting, if we follow convention that each declaration begins a new block. Static scope with access links int x=1。 function g(z) = x+z。 function f(y) = { int x = y+1。 return g(y*x) }。 f(3)。 x 1 x 4 y 3 z 12 outer block f(3) g(12) control link access link g … f … control link access link control link access link access link control link Use access link to find global variable: – Access link is always set to frame of closest enclosing lexical block – For function body, this is block that contains function declaration Tail recursion (firstorder case) ?Function g makes a tail call to function f if ? Return value of function