unk is a memoization library for Clojure that provides an extension to the base capabilities.
unk is easy to use.
[unk "0.9.0"]
<dependency>
<groupId>unk</groupId>
<artifactId>unk</artifactId>
<version>0.9.0</version>
</dependency>
unk can be used in place of clojure.core.memoize
.
(def slowly (fn [x] (Thread/sleep 3000) x))
(time [(slowly 9) (slowly 9)])
; "Elapsed time: 6000.63 msecs"
;=> [9 9]
This calls for fogus.unk.memo
:
(def sometimes-slowly (manipulable-memoize slowly))
(time [(sometimes-slowly 108) (sometimes-slowly 108)])
; "Elapsed time: 3000.409 msecs"
;=> [108 108]
fogus.unk.memo
is a raw replacement for
clojure.core.memoize
– it does the exact same thing. All of
unk’s memoization strategies can operate as replacements for
memoize
, except that each displays its own operational
characteristics.
There is a basic Fifo cache.
(def id (memo-fifo identity 2))
This creates a new function id
operating with a
First-in-first-out cache of size two. How would this operate under
use?
(id 42)
;=> 42
What does the cache look like?
(snapshot id)
;=> {[42] 42}
Simple enough. But what if we cross the size limit?
(id 108)
;=> 108
(id 9)
;=> 9
(snapshot id)
;=> {[108] 108, [9] 9}
Of course, the first entry in the cache 42
has been
removed.
unk also provides a Least-recently-used (LRU), Least-used (LU),
Time-to-live (TTL, in ms), and a basic cache (i.e. like
memo
) built on soft references.1. I
will not go into incredible detail about those here, but I am working on
documentation that will explain more and include more thorough usage
scenarios.
Because I needed it on a project. I didn’t simply need memoization. I
needed pluggable (LRU, LU, TTL, FIFO, etc.), manipulable
(memo-swap!
, memo-clear!
,
memo-unwrap
, etc.), extendable
(build-memoizer
), and inspect-able (snapshot
,
etc.) memoization. It’s as simple as that. I suspect you may need
it too. This is why I’m announcing it now, rather than waiting until
it’s fully documented.
For now you can view the annotated unk source code for some ideas.
unk is inspired by section 12.4 in The Joy of Clojure which is in turn inspired by the memoization philosophy espoused by Christophe Grand, Eugen Dück, and Meikel Brandmeyer. In addition, I would like to thank Chas Emerick for his memoization based on SoftReferences. This project would be nothing2 without their original vision. Thanks gentlemen!
:F