(define deep-recur-list
  (lambda (seed list-proc atom-proc)
    (letrec
      ((helper
	(lambda (ls)
	  (cond ((null? ls) seed)
		((pair? (car ls))
		 (list-proc (helper (car ls))
			    (helper (cdr ls))))
		(else
		 (atom-proc (car ls)
			    (helper (cdr ls))))))))
      helper)))

(define reverse-all
  (deep-recur-list
   ()
   (lambda (x y) (append y (list x)))
   (lambda (x y) (append y (list x)))))
   
(define sum-all
  (deep-recur-list 0 + +))

(define product-all
  (deep-recur-list 1 * *))

(define filter-all-c
  (lambda (pred)
    (deep-recur-list 
     ()
     cons
     (lambda (x y)
       (if (pred x)
	   (cons x y)
	   y)))))

(define filter-all
  (lambda (pred ls)
    ((filter-all-c pred) ls)))

(define delete-all-c
  (lambda (item)
    (deep-recur-list
     ()
     cons
     (lambda (x y)
       (if (eq? x item)
	   y
	   (cons x y))))))

(define delete-all
  (lambda (item ls)
    ((delete-all-c item) ls)))

(define deep-recur-pair
  (lambda (pair-proc atom-proc)
    (letrec
      ((helper
	(lambda (s)
	  (if (pair? s)
	      (pair-proc (helper (car s))
			 (helper (cdr s)))
	      (atom-proc s)))))
      helper)))

(define sum-all
  (deep-recur-pair + (lambda (x) (if (null? x) 0 x))))

(define product-all
  (deep-recur-pair * (lambda (x) (if (null? x) 1 x))))

(define copy
  (deep-recur-pair cons (lambda (x) x)))

(define atom-map-c
  (lambda (proc)
    (deep-recur-pair
     cons
     (lambda (x) (if (null? x) () (proc x))))))

(define atom-map
  (lambda (proc s)
    ((atom-map-c proc) s)))

(define filter-all-c
  (lambda (pred)
    (deep-recur-pair
     (lambda (x y)
       (if (or (pair? x) (pred x))
	   (cons x y)
	   y))
     (lambda (x) x))))

(define filter-all
  (lambda (pred s)
    ((filter-all-c pred) s)))

(define swap-c
  (lambda (x y)
    (deep-recur-pair
     cons
     (lambda (s)
       (cond ((eq? s x) y)
	     ((eq? s y) x)
	     (else
	      s))))))

(define swap
  (lambda (x y s)
    ((swap-c x y) s)))