Unk
unk is a memoization library for Clojure that provides an extension to the base capabilities.
Using unk
unk is easy to use.
Leiningen
[unk "0.9.0"]
Maven
<dependency>
<groupId>unk</groupId>
<artifactId>unk</artifactId>
<version>0.9.0</version>
</dependency>
Source
Straight-up replacement
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.
Fifo
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.
And the rest…
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.
Why unk?
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.
The true story of unk
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
7 Comments, Comment or Ping
Meikel
You (or someone else over there at Relevance) might want to invalidate this JIRA ticket then. It won’t go into some form of contrib anyway. It was based on the original thread.
Furthermore I’d like to mention cache-dot-clj, which is also based on the original thread and does similar things you needed.
Jun 21st, 2011
Rich Hickey
Hmm, I smell a composite here (cache + memoizer) – can you pull them apart? (I see the caches there, but they don’t implement any common map/lookup interfaces). FYI:
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapMaker.html
And LIRS support, maybe?
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.116.2184
Jun 21st, 2011
fogus
@Meikel
I’m not sure that ticket needs to be invalidated since Unk is not a part of contrib. I am also aware of cache-dot.clj since it’s development occurred mostly in parallel with Unk (although it was called Keepsake back then). Different approaches built on the solid core. cache-dot.clj has had more eyes on it and likely has more use in production.
Jun 21st, 2011
fogus
@Rich,
They are (in effect) pulled apart, the matter of making them separate libraries would be mostly mechanical. I would love to add the lookup interfaces, but time is fleeting at the moment.
Thanks for the pointer to LIRS, I will read up on it ASAP.
Jun 21st, 2011
Sebastián Galkin
Why is (< 0 ttl) a precondition for ttl-cache-factory? I think it makes sense to allow ttl=0, for instance, I’d use it set to 0 during testing. It’s a nice parameter which allows degrading to no cache when = 0.
Jul 10th, 2011
fogus
@paraseba
Agreed. I will make the change post-haste. Thanks
Jul 10th, 2011
Sebastián Galkin
@fogus great! I’ll put this to good use. Thanks
Jul 10th, 2011
Reply to “Unk”