Advertisement
timothy235

sicp-3-2-the-environment-model-of-evaluation

Feb 23rd, 2017
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 5.88 KB | None | 0 0
  1. #lang racket
  2.  
  3. #|
  4. An environment is a sequence of frames, and a frame is a table of bindings.
  5. Bindings assign values to variables.  Every expression is evaluated with
  6. respect to some environment.  The value of a variable is obtained from the
  7. first frame in the environment containing the variable.
  8.  
  9. A procedure object is a pair consisting of code and an environment.  The code
  10. consists of the formal parameters and the function body.  The environment is
  11. the environment of definition, also called the enclosing environment.
  12.  
  13. When you call a function, you first create a new frame below the enclosing
  14. environment and bind the formal parameters to the passed values in this frame.
  15. Then the body of the function is evaluated in this new binding environment.
  16. |#
  17.  
  18. ;;;;;;;;;
  19. ;; 3.9 ;;
  20. ;;;;;;;;;
  21.  
  22. #|
  23. Every time we call a function, the body of the function is evaluated in the
  24. binding environment.  So calling a recursive function will create an
  25. environment structure consisting of several parallel binding frames, one for
  26. each call, all just below the enclosing environment.  In particular, you do not
  27. get a descending chain of binding frames;  that only happens when you have
  28. local definitions.
  29.  
  30. The evaluation of recursive factorial applied to 6, will create an environment
  31. structure consisting of six parallel binding frames.  In the first binding
  32. frame, n is bound to 6.  In the second, n is bound to 5, and so on, until, in
  33. the last binding frame, n is bound to 1.  When n is 1, the body of factorial
  34. can be evaluated without making any more recursive calls, so this is the last
  35. frame created.
  36.  
  37. The evaluation of iterative factorial applied to 6, will call factorial once
  38. and fact-iter seven times.  So that function call will create an environment
  39. structure consisting of eight parallel binding frames, one for factorial where
  40. n is bound to 6, and seven for fact-iter where product, counter, and max-count
  41. are bound to their appropriate values.
  42. |#
  43.  
  44. ;;;;;;;;;;
  45. ;; 3.10 ;;
  46. ;;;;;;;;;;
  47.  
  48. ;; Describe the environment structure for:
  49.  
  50. (define (make-withdraw initial-amount)
  51.   (let ([balance initial-amount])
  52.     (lambda (amount)
  53.       (cond [(>= balance amount)
  54.              (set! balance (- balance amount))
  55.              balance]
  56.             [else "Insufficient funds"]))))
  57.  
  58. #|
  59. Note that the let form is syntactic sugar for:
  60.  
  61. (define (make-withdraw initial-amount)
  62.   ((lambda (balance)
  63.      (lambda (amount)
  64.        (cond [(>= balance amount)
  65.               (set! balance amount)
  66.               balance]
  67.              [else "Insufficient funds"])))
  68.    initial-amount))
  69. |#
  70.  
  71. (define W1 (make-withdraw 100))
  72.  
  73. #|
  74. W1 is created in the global environment.  Its value is the result of calling
  75. the outer lambda, the function of balance, on initial-amount.  This value will
  76. be the inner lambda, the function of amount.
  77.  
  78. So to evaluate W1, we first create a binding frame E1 below the global
  79. environment, where we bind balance to initial-amount and define the inner
  80. lambda, the function of amount.  The enclosing environment for the inner lambda
  81. is the binding environment for the outer lambda.
  82. |#
  83.  
  84. (W1 50)
  85. ;; 50
  86.  
  87. #|
  88. Calling W1, whose value is the inner lambda, on 50, creates a new binding frame
  89. below E1, where amount is bound to 50, and the body of the inner lambda is
  90. evaluated.
  91. |#
  92.  
  93. (define W2 (make-withdraw 100))
  94.  
  95. #|
  96. If we call make-withdraw again to create another account W2, W2 will also be
  97. created in the global environment, and its value will also be the identical
  98. inner lambda, the function of amount.  However, this time, the enclosing
  99. environment for the inner lambda will not be E1, but rather the new binding
  100. frame for the second call, which will be parallel to E1.
  101. |#
  102.  
  103. (W2 10)
  104. ;; 90
  105.  
  106. ;;;;;;;;;;
  107. ;; 3.11 ;;
  108. ;;;;;;;;;;
  109.  
  110. ;; Describe the environment structure for:
  111.  
  112. (define (make-account balance)
  113.   (define (withdraw amount)
  114.     (cond [(>= balance amount)
  115.            (set! balance (- balance amount))
  116.            balance]
  117.           [else "Insufficient funds"]))
  118.   (define (deposit amount)
  119.     (set! balance (+ balance amount))
  120.     balance)
  121.   (define (dispatch m)
  122.     (cond [(eq? m 'withdraw) withdraw]
  123.           [(eq? m 'deposit) deposit]
  124.           [else (error "Unknown request -- MAKE-ACCOUNT:" m)]))
  125.   dispatch)
  126.  
  127. (define acc (make-account 50))
  128.  
  129. #|
  130. acc is defined in the global environment.  Its value is the result of calling
  131. make-account on 50.  Since make-account is defined in the global environment,
  132. calling make-account creates a binding frame E1, below the global environment,
  133. where balance is bound to 50 and the body of make-account is evaluated.
  134. Evaluating the body of make-account in E1 creates new functions withdraw,
  135. deposit, and dispatch, all of which have E1 as their enclosing environment.
  136. The value of acc is this dispatch function, the one defined inside E1.
  137. |#
  138.  
  139. ((acc 'deposit) 40)
  140. ;; 90
  141.  
  142. #|
  143. Calling acc on 'deposit returns the deposit function defined inside E1.
  144. Calling deposit on 40, creates a new binding frame, below E1, where amount is
  145. bound to 40, and the body of the deposit function is evaluated.
  146. |#
  147.  
  148. ((acc 'withdraw) 60)
  149. ;; 30
  150.  
  151. #|
  152. Similarly, calling acc on 'withdraw returns the withdraw function defined
  153. inside E1.  Calling withdraw on 60, creates a new binding frame, below E1,
  154. where amount is bound to 60, and the body of the withdraw function is
  155. evaluated.
  156. |#
  157.  
  158. (define acc2 (make-account 100))
  159.  
  160. #|
  161. Calling make-account a second time creates a new binding frame E2, below the
  162. global environment, where balance is bound to 100, and functions withdraw,
  163. deposit, and dispatch are defined.  These functions have the exact same code,
  164. formal parameters and body, as they do for acc, but their enclosing environment
  165. is E2, not E1.
  166.  
  167. In particular, the local state for acc is kept in E1, while the local state for
  168. acc2 is kept in E2.  The only part of the environment structure common to acc
  169. and acc2 is the global environment.
  170. |#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement