(define reverse-it
  (lambda (ls acc)
    (if (null? ls)
	acc
	(reverse-it (cdr ls) (cons (car ls) acc)))))

(define reverse
  (lambda (ls)
    (reverse-it ls '())))

(define fact-it
  (lambda (x acc)
    (if (zero? x)
	acc
	(fact-it (sub1 x) (* x acc)))))

(define fast-fact
  (lambda (x)
    (fact-it x 1)))

(define fact
  (lambda (x)
    (if (= x 0)
	1
	(* x (fact (sub1 x))))))

(define fib-it
  (lambda (x acc0 acc1)
    (if (= x 0) 
	acc0
	(fib-it (sub1 x) acc1 (+ acc0 acc1)))))

(define fast-fib
  (lambda (x)
    (fib-it x 0 1)))

(define fib
  (lambda (x)
    (if (<= x 1)
	x
	(+ (fib (- x 1)) (fib (- x 2))))))

(define N 10)

;; e = 2.718281828... = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + ...
(define e-it
  (lambda (i acc1 acc2)
    (if (= i N)
	acc2
	(e-it (add1 i) (* acc1 i) (+ acc2 (/ 1.0 acc1))))))

(define e
  (lambda ()
    (e-it 1 1 0.0)))

(define member?
  (lambda (item ls)
    (and (not (null? ls))
	 (or (eq? item (car ls))
	     (member? item (cdr ls))))))