aboutsummaryrefslogtreecommitdiff
path: root/gn/cache/memoize.scm
blob: b79e0261b21c503a4c1e89df12d222dc947c61de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
;; Defines simple memoization functions. Currently it uses an alist -
;; we should change that to a hash. Also we want the cache to expire
;; after some time. memoize2 is now a separate function to deal
;; specifically with two return values. That is not ideal either.

;; Basically lifted from
;; https://lispdreams.wordpress.com/2016/04/08/lisp-memoization-techniques/

(define-module (gn cache memoize)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-13) ; hash table for memoize
  #:use-module (srfi srfi-11) ; let-values

  #:export (memoize
            memoize2))

(define (memoize f)
  "Simple memoize just uses alists at this point and does not expire"
  (let ((result-table '()))
    (lambda (. args)
      (let ((cache-value (assoc args result-table)))
	(if cache-value
	    (cdr cache-value)
	    (let ((result (apply f args)))
	      (set! result-table
                    (alist-cons args result result-table)) result))))))

(define (memoize2 f)
  "Simple memoize functions that returns values pair and uses alists at this point and does not expire"
  (let ((result-table '()))
    (lambda (. args)
      (let ((c (assoc args result-table)))
	(if c
	    (values (car (cdr c)) (car (cdr (cdr c))))
	    (let-values (((r1 r2) (apply f args)))
	      (set! result-table
                    (alist-cons args (list r1 r2) result-table)) (values r1 r2)))))))