(define flat-recur
  (lambda (seed list-proc)
    (letrec
      ((helper
	(lambda (ls)
	  (if (null? ls)
	      seed
	      (list-proc (car ls) 
			 (helper (cdr ls)))))))
      helper)))

(define sum
  (flat-recur 0 +))

(define product
  (flat-recur 1 *))

(define length
  (flat-recur
    0
    (lambda (x y) (add1 y))))

(define add1-to-all
  (flat-recur
    ()
    (lambda (x y) (cons (add1 x) y))))

(define sum-many
  (lambda args
    ((flat-recur 0 +) args)))

(define list
  (lambda args
    ((flat-recur () cons) args)))

(define compose-many
  (lambda args
    ((flat-recur
      (lambda (x) x)
      (lambda (f g) (lambda (x) (f (g x)))))
     args)))

(define caddddr
  (compose-many car cdr cdr cdr cdr))

(define member?-c
  (lambda (item)
    (flat-recur 
     #f 
     (lambda (x y) (or (equal? x item) y)))))

(define member?
  (lambda (item ls)
    ((member-c item) ls)))

(define filter-c
  (lambda (pred)
    (flat-recur 
      ()
      (lambda (x y)
        (if (pred x)
	    (cons x y)
	    y)))))

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

(define map-c
  (lambda (proc)
    (flat-recur
      ()
      (lambda (x y) (cons (proc x) y)))))

(define map
  (lambda (proc ls)
    ((map-c proc) ls)))