# (chibi memoize)

Memory and persistent caching with various levels of control, based on a combination of lru-cache from Hato and an older memoization library for Gauche.

#### `(define-memoized (proc x ...) . body)
(define-memoized (proc . x) . body)`

Analagous to the procedure form of `define` but automatically memoizes the function. Uses `equal?` for equality comparisons and reasonable defaults - for finer grained control use `memoize`.

#### `(make-memoizer proc arity cache . o)`

#### `(memoize proc . o)`

Returns a memoized version of the procedure `proc`. By default uses a least-recently-used (LRU) cache, which can be tuned with the following keyword arguments:

<items>
- cache: an explicit pre-existing cache (LRU or hash-table)
- equal: an equality predicate defaulting to `equal?`
- hash: a hash function to match the equality predicate, defaulting to `hash` from `(srfi 69)`
- init-size: a hint for the initial size of the backing hash table
- size-limit: the maximum size of the cache
- compute-size: compute the size of a cache entry
</items>

`compute-size` is a procedure of two arguments, the key and value to be stored, and defaults to a constant 1 per entry. After every insertion the oldest elements will be removed until the size is under `size-limit`. You may find

`(lambda (k v) (+ (object-size k) (object-size v)))`

using `object-size` from `(chibi ast)` to be a useful `compute-size`.

If `size-limit` is `#f` then the cache is unlimited, and a simple hash-table will be used in place of an LRU cache.

#### `(memoize-file-loader proc . o)`

Equivalent to memoize except that the procedure's first argument must be a pathname. If the corresponding file has been modified since the memoized value, the value is recomputed. Useful to automatically reflect external changes to a file-backed resource. The additional keyword argument `reloader?:`, if true, indicates that the result of loading is itself a procedure which should check for updates on each call.

#### `(memoize-to-file proc . o)`

Returns a memoized version of the procedure `proc` which stores the memoized results persistently in a file. Garbage collection of the files is left as an external task for monitoring tools or cron jobs.

Accepts the following keyword arguments:

<items>
- args-encoder: procedure which takes the arguments as a single list, and returns a string representation suitable for use as a (base) file name
- proc-name: the name of the procedure, to use a subdir of memo-dir to distinguish from other memoized procedures
- memo-dir: the directory to store results in, defaulting to ~/.memo/
- file-validator: validator to run on the existing file - if it returns false, the file is considered bad and the result recomputed
- validator: validator to run on the result of reading the file
- read: the read procedure to extract the result from the file
- write: the write procedure to write the result to the file
</items>

#### `(make-lru-cache . o)`

Creates a new empty LRU object. The same keyword arguments as in `memoize` are available, except of course for `cache`.

#### `(lru-ref lru key . o)`

Looks up `key` in the cache LRU. If not found returns #f, unless `compute` is given in which case `compute` is applied to `key` to determine the return value. This does not update the cache.

#### `(lru-ref! lru key compute)`

Identical to lru-ref except that it updates the cache on a miss.

#### `(lru-set! lru key value)`

Directly set a value in the cache.

#### `(hash-table-ref! table key proc)`