;; Parameter passing variations

;;
;; call-by-value interpreter
;;
(load "3-7.scm")

;; passing a variable as argument
(run
"
  let y = 100
  in let inc = proc (x) 
                   let d = set x = add1(x)
                   in x
      in +((inc y), (inc y))
")

;;
;; call-by-reference interpreter
;;
(load "3-8ref.scm")

;; e.g.:

;; passing a variable as argument
(run
"
  let y = 100
  in let inc = proc (x) 
                   let d = set x = add1(x)
                   in x
      in +((inc y), (inc y))
")

(run 
"
let x = 13
    f = proc (y) set y = add1(y)
in begin
    (f x); 
    x
   end
")

;; changing the parameters
(run 
"
let a = 3
    b = 4
    swap = proc (x, y)
             let temp = x
             in begin
                  set x = y;
                  set y = temp
                end
in begin
     (swap a b);
     -(a,b)
   end
")

;; Exercise:  what would it return under call-by-value?

;;
;; call-by-name interpreter
;;
(load "3-8name.scm")

;; e.g.:

;; passing a variable as argument
(run
"
let x = 13
    f = proc (y) set y = add1(y)
in begin
    (f x); 
    x
   end
")

(run 
"
let a = 3
    b = 4
    swap = proc (x, y)
             let temp = x
             in begin
                  set x = y;
                  set y = temp
                end
in begin
     (swap a b);
     -(a,b)
   end
"
)

;; ignoring an argument expression
(run
"
let a = 3
in let f = proc () set a = add1(a)
       g = proc (x) 11
   in begin 
        (g (f));
        a
      end
")

;; "myif" as a procedure in the defined language
(run
"
let myif = proc (test, texp, fexp)
                 if test then texp else fexp
in let x=4 y=0 
    in (myif zero?(y) x *(x,y))   % if we had division as a primitive,
                                           % the example would be more interesting.
")

;; invoking an argument expression multiple times
(run 
"
let g = let count = 0 in proc () begin 
                                   set count = add1(count); 
                                   count
                                 end
in (proc(x) +(x,x)
    (g))
") 

;;
;; call-by-need interpreter
;;
(load "3-8need.scm")

;; passing a variable as argument
(run 
"
let x = 13
    f = proc (y) set y = add1(y)
in begin
    (f x); 
    x
   end
")

(run 
"
let a = 3
    b = 4
    swap = proc (x, y)
             let temp = x
             in begin
                  set x = y;
                  set y = temp
                end
in begin
     (swap a b);
     -(a,b)
   end
")

;; ignoring an argument expression
(run
"
let a = 3
in let f = proc () set a = add1(a)
       g = proc (x) 11
   in begin 
        (g (f));
        a
      end
")

;; "myif" as a procedure in the defined language
(run
"
let myif = proc (test, texp, fexp)
                 if test then texp else fexp
in let x=4 y=0 
    in (myif zero?(y) x *(x,y))   % if we had division as a primitive,
                                           % the example would be more interesting.
")

;; invoking an argument expression multiple times
(run 
"
let g = let count = 0 in proc () begin 
                                   set count = add1(count); 
                                   count
                                 end
in (proc(x) +(x,x)
    (g))
") 

;; equivalent to:
(run 
"
let g = let count = 0 in proc () begin 
                                   set count = add1(count); 
                                   count
                                 end
in let f = proc(x) +(x,x)
    in (f (g))
") 

;; Try out exercise 3.61

;; Take a look at a language with statements in Section 3.9
;; See 3-9.scm for its interpreter.
