;; Memoization.
;; @note Using dynamically bound variable (Parameters).
(use-modules (srfi srfi-19)
(ice-9 format))
;; Time.
(define (process-time)
(let ((now (current-time time-process)))
(+ (time-second now) (/ (time-nanosecond now) 1E9))))
(define (timeit thunk)
(let ((t (process-time)))
(thunk)
(format #t "Elapsed: ~,6Fs~%" (- (process-time) t))))
;; Memo
(define (memo-list f)
(let ((m '()))
(lambda (n)
(unless (assoc-ref m n)
(set! m (acons n (f n) m)))
(assoc-ref m n))))
(define (memo-hash f)
(let ((m (make-hash-table)))
(lambda (n)
(unless (hash-ref m n)
(hash-set! m n (f n)))
(hash-ref m n))))
;; Show.
(define fib
(make-parameter
(lambda (n)
(cond
((= n 0) 0)
((= n 1) 1)
(else
(+ ((fib) (- n 2)) ((fib) (- n 1))))))))
(define (make-f f)
(lambda ()
(parameterize ((fib f))
(format #t "~A~%" ((fib) 30)))))
(for-each timeit
(list (make-f (fib))
(make-f (memo-list (fib)))
(make-f (memo-hash (fib)))))
OzsgTWVtb2l6YXRpb24uCjs7IEBub3RlIFVzaW5nIGR5bmFtaWNhbGx5IGJvdW5kIHZhcmlhYmxlIChQYXJhbWV0ZXJzKS4KCih1c2UtbW9kdWxlcyAoc3JmaSBzcmZpLTE5KQogICAgICAgICAgICAgKGljZS05IGZvcm1hdCkpCgo7OyBUaW1lLgoKKGRlZmluZSAocHJvY2Vzcy10aW1lKQogIChsZXQgKChub3cgKGN1cnJlbnQtdGltZSB0aW1lLXByb2Nlc3MpKSkKICAgICgrICh0aW1lLXNlY29uZCBub3cpICgvICh0aW1lLW5hbm9zZWNvbmQgbm93KSAxRTkpKSkpCgooZGVmaW5lICh0aW1laXQgdGh1bmspCiAgKGxldCAoKHQgKHByb2Nlc3MtdGltZSkpKQogICAgKHRodW5rKQogICAgKGZvcm1hdCAjdCAiRWxhcHNlZDogfiw2RnN+JSIgKC0gKHByb2Nlc3MtdGltZSkgdCkpKSkKCjs7IE1lbW8KCihkZWZpbmUgKG1lbW8tbGlzdCBmKQogIChsZXQgKChtICcoKSkpCiAgICAobGFtYmRhIChuKQogICAgICAodW5sZXNzIChhc3NvYy1yZWYgbSBuKQogICAgICAgICAgICAgIChzZXQhIG0gKGFjb25zIG4gKGYgbikgbSkpKQogICAgICAoYXNzb2MtcmVmIG0gbikpKSkKCihkZWZpbmUgKG1lbW8taGFzaCBmKQogIChsZXQgKChtIChtYWtlLWhhc2gtdGFibGUpKSkKICAgIChsYW1iZGEgKG4pCiAgICAgICh1bmxlc3MgKGhhc2gtcmVmIG0gbikKICAgICAgICAgICAgICAoaGFzaC1zZXQhIG0gbiAoZiBuKSkpCiAgICAgIChoYXNoLXJlZiBtIG4pKSkpCgo7OyBTaG93LgoKKGRlZmluZSBmaWIKICAobWFrZS1wYXJhbWV0ZXIKICAgKGxhbWJkYSAobikKICAgIChjb25kCiAgICAgKCg9IG4gMCkgMCkKICAgICAoKD0gbiAxKSAxKQogICAgIChlbHNlCiAgICAgICgrICgoZmliKSAoLSBuIDIpKSAoKGZpYikgKC0gbiAxKSkpKSkpKSkKCihkZWZpbmUgKG1ha2UtZiBmKQogIChsYW1iZGEgKCkKICAgIChwYXJhbWV0ZXJpemUgKChmaWIgZikpCiAgICAgIChmb3JtYXQgI3QgIn5BfiUiICgoZmliKSAzMCkpKSkpCgooZm9yLWVhY2ggdGltZWl0CiAgICAgICAgICAobGlzdCAobWFrZS1mIChmaWIpKQogICAgICAgICAgICAgICAgKG1ha2UtZiAobWVtby1saXN0IChmaWIpKSkKICAgICAgICAgICAgICAgIChtYWtlLWYgKG1lbW8taGFzaCAoZmliKSkpKSk=