(define memoize1
  (lambda (proc)
    (let ((table (make-vector 10000 '())))
      (lambda (n)
	(let ((result (vector-ref table n)))
	  (if (null? result)
	      (let ((result (proc n)))
		(vector-set! table n result)
		result
		)
	      result))))))

(define slow-fib
  (lambda (n)
    (cond ((= n 0) 0)
	  ((= n 1) 1)
	  (else
	   (+ (slow-fib (- n 1))
	      (slow-fib (- n 2)))))))

(define fast-second-time-fib
  (memoize1 slow-fib))

(define fast-fib
 (memoize1
  (lambda (n)
    (cond ((= n 0) 0)
	  ((= n 1) 1)
	  (else
	   (+ (fast-fib (- n 1))
	      (fast-fib (- n 2))))))))

;; needed for expr->string
(require-library "string.ss")

(define memoize2
  (lambda (proc)
    (let ((table (make-hash-table)))
      (lambda (s)
	(let* ((key (string->symbol (expr->string s)))
	       (result (hash-table-get table key (lambda () #f))))
	  (if (not result)
	      (let ((result (proc s)))
		(hash-table-put! table key result)
		result)
	      result))))))