;; fold.scm
;; 
;;

(define (foldr op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence) (foldr op initial (cdr sequence)))))

;; (foldr + 0 '(1 2 3 4))
;; turns into
;; (+ 1 (+ 2 (+ 3 (+ 4 0))))


(define (add a b)
  (printf "  debug: (add ~a ~a).\n" a b)
  (+ a b))

(printf "-- starting foldr --\n")
(printf "(foldr add 0 '(1 2 3 4)) is ~a.\n"
        (foldr add 0 '(1 2 3 4)))

(newline)

;; ---------------------------------

(define (foldl op initial sequence)
  (define (iterate answer remaining)
    (if (null? remaining)
        answer
        (iterate (op answer (car remaining)) (cdr remaining))))
  (iterate initial sequence))

;; (fold0 + 0 '(1 2 3 4))
;; turns into
;; (+ (+ (+ (+ 0 1) 2) 3) 4)


(printf "-- starting foldl --\n")
(printf "(foldl add 0 '(1 2 3 4)) is ~a.\n"
        (foldl add 0 '(1 2 3 4)))


;; running it :
;;
;; $ scheme fold.scm
;;
;; -- starting foldr --
;;   debug: (add 4 0).
;;   debug: (add 3 4).
;;   debug: (add 2 7).
;;   debug: (add 1 9).
;; (foldr add 0 '(1 2 3 4)) is 10.
;;
;; -- starting foldl --
;;   debug: (add 0 1).
;;   debug: (add 1 2).
;;   debug: (add 3 3).
;;   debug: (add 6 4).
;; (foldl add 0 '(1 2 3 4)) is 10.
;;