
;; Further examples highlighting the difference between static and
;; dynamic binding.

(load "9d.ss")

;;
;; Exercise 3.32
;;

;; The following code does not work under static binding, why?  (it
;; does under dynamic binding, why?)

(run
"
  let fact = proc (n) add1(n)
  in let fact = proc (n)
                       if n
                       then *(n, (fact sub1(n)))
                       else 1
      in (fact 5)
")

(run
"
      let fact = proc (n)
                       if n
                       then *(n, (fact sub1(n)))
                       else 1
      in (fact 5)
")

(run
"
     let even = proc(x)
                       if x
                       then (odd sub1(x))
                       else 1
          odd = proc(x)
                       if x
                       then (even sub1(x))
                       else 0
     in (odd 5)
")

;; Exercise 3.33; run it under dynamic binding and explain the difference.
;;  Also, why doesn't it work under static binding?  

 (run "
let a = 3
     p = proc() a
in let f = proc (x) (p)
        a = 5
    in (f 2)
") 

(run "
let a = 3
     p = proc() a
in let f = proc (a) (p)
        a = 5
    in (f 2)
")

;; the following (probably the textbook authors' intention!) works
;; under static binding, and produces different answers under dynamic
;; binding with different names for f's formal parameter.

(run "
let a = 3
in let p = proc() a
    in let f = proc (a) (p)
            a = 5
        in (f 2)
")

;;
;; Exercise: why does the following "curry" not work with dynamic
;; binding?  (it works with static binding.)

(run
"
  let curry = proc (f) proc (x) proc (y) (f x y)
       plus = proc (x,y) +(x,y)
  in (((curry plus) 2) 3)
")

;; Answer: because when "f" is evaluated, the evaluation of "(curry
;; plus)" has already completed, and the binding from "f" to "plus" is
;; no longer visible.

;; The same problem applies to the following code:

(run
"
  let inc = proc (x) add1(x)
      apply = proc (f) proc (x) (f x)
      in ((apply inc) 5)
")

;; when "f" is to be applied, it is no longer bound to "inc"; you can
;; "fix" the problem as follows:

(run
"
  let inc = proc (x) add1(x)
  in let f = inc
          apply = proc (f) proc (x) (f x)
          in ((apply inc) 5)
")

;; but the argument to "apply" is completely ignored, e.g.:

(run
"
  let inc = proc (x) add1(x)
      dec = proc (x) sub1(x)
  in let f = inc
          apply = proc (f) proc (x) (f x)
          in ((apply dec) 5)
")

;; what does the code return under static binding?  why?
