15 API Reference
Last modified: 2026-02-08
Setup
A few preparations for the code examples below:
(require '[scicloj.pocket :as pocket])(def cache-dir "/tmp/pocket-demo-reference")(pocket/set-base-cache-dir! cache-dir)10:06:46.939 INFO scicloj.pocket - Cache dir set to: /tmp/pocket-demo-reference
"/tmp/pocket-demo-reference"(pocket/cleanup!)10:06:46.939 INFO scicloj.pocket - Cache cleanup: /tmp/pocket-demo-reference
{:dir "/tmp/pocket-demo-reference", :existed false}(defn expensive-calculation
"Simulates an expensive computation"
[x y]
(println (str "Computing " x " + " y " (this is expensive!)"))
(Thread/sleep 400)
(+ x y))Reference
*base-cache-dir*
Base directory for cache storage.
Resolved with precedence: binding > set-base-cache-dir! > POCKET_BASE_CACHE_DIR env var > pocket.edn :base-cache-dir > pocket-defaults.edn (library default: .cache/pocket).
The current value:
pocket/*base-cache-dir*"/tmp/pocket-demo-reference"set-base-cache-dir!
[dir]
Set the base cache directory by altering *base-cache-dir*. Returns the directory path.
(pocket/set-base-cache-dir! "/tmp/pocket-demo-2")10:06:46.942 INFO scicloj.pocket - Cache dir set to: /tmp/pocket-demo-2
"/tmp/pocket-demo-2"pocket/*base-cache-dir*"/tmp/pocket-demo-2"Restore it for the rest of the notebook:
(pocket/set-base-cache-dir! cache-dir)10:06:46.942 INFO scicloj.pocket - Cache dir set to: /tmp/pocket-demo-reference
"/tmp/pocket-demo-reference"config
[]
Return the effective resolved configuration as a map. Useful for inspecting which cache directory, mem-cache policy, storage policy, and filename length limit are in effect after applying the precedence chain.
Inspect the current effective configuration:
(pocket/config){:base-cache-dir "/tmp/pocket-demo-reference",
:mem-cache {:policy :lru, :threshold 256},
:storage :mem+disk,
:filename-length-limit 240}cached
[func & args]
Create a cached computation (returns IDeref).
The computation is executed on first deref and cached to disk. Subsequent derefs load from cache if available.
func must be a var (e.g., #'my-fn) or keyword (e.g., :train) for stable cache keys. Keywords are useful for extracting from cached maps: (cached :train split-c).
Storage policy is controlled by *storage* (see set-storage!). Use caching-fn with an opts map for per-function overrides.
cached returns a Cached object — the computation is not yet executed:
(def my-result (pocket/cached #'expensive-calculation 100 200))(type my-result)scicloj.pocket.impl.cache.CachedThe computation runs when we deref:
(deref my-result)10:06:46.945 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 100 + 200 (this is expensive!)
300Derefing again loads from cache (no recomputation):
(deref my-result)300caching-fn
[f]
[f opts]
Wrap a function to automatically cache its results.
Returns a new function where each call returns a Cached object (IDeref). Deref the result to trigger computation or load from cache. f must be a var (e.g., #'my-fn) or keyword for stable cache keys.
Optionally accepts an options map to override configuration per-function:
:storage—:mem+disk,:mem, or:none(overrides*storage*):cache-dir— base cache directory (overrides*base-cache-dir*):mem-cache— in-memory cache options (overrides*mem-cache-options*):filename-length-limit— max filename length before SHA-1 fallback (overrides*filename-length-limit*)
caching-fn wraps a function so that every call returns a Cached object:
(def my-caching-fn (pocket/caching-fn #'expensive-calculation))(deref (my-caching-fn 3 4))10:06:47.364 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 3 + 4 (this is expensive!)
7Same args hit the cache:
(deref (my-caching-fn 3 4))7caching-fn accepts an optional map to override per-function configuration:
(pocket/caching-fn #'f {:storage :mem}) ;; in-memory only
(pocket/caching-fn #'f {:storage :none}) ;; identity tracking only
(pocket/caching-fn #'f {:cache-dir "/tmp/alt"}) ;; alternate cache dirSee the Configuration chapter for details on storage modes and the full option map.
maybe-deref
[x]
Deref if x implements IDeref, otherwise return x as-is.
Useful in pipeline functions that may receive either Cached or plain values.
A plain value passes through unchanged:
(pocket/maybe-deref 42)42A Cached value gets derefed:
(pocket/maybe-deref (pocket/cached #'expensive-calculation 100 200))300->id
[x]
Return a cache key representation of a value. Dispatches via the PIdentifiable protocol.
For derefed Cached values, returns the same lightweight identity as the original Cached reference — the origin registry preserves the link automatically (see cache_keys notebook for details).
A var’s identity is its fully-qualified name:
(pocket/->id #'expensive-calculation)pocket-book.api-reference/expensive-calculationA map’s identity is itself (maps are deep-sorted later for stable cache paths):
(pocket/->id {:b 2 :a 1}){:b 2, :a 1}A Cached object’s identity captures the full computation — function name and argument identities — without running it:
(pocket/->id (pocket/cached #'expensive-calculation 100 200))(pocket-book.api-reference/expensive-calculation 100 200)nil is handled as well:
(pocket/->id nil)nilA derefed Cached value carries its origin identity (for maps, vectors, sets, and datasets):
(defn make-config [x y] {:x x :y y})(let [c (pocket/cached #'make-config 100 200)]
(= (pocket/->id (deref c)) (pocket/->id c)))10:06:47.778 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/make-config
trueset-mem-cache-options!
[opts]
Configure the in-memory cache. Resets it, discarding any currently cached values.
Supported keys:
:policy—:lru,:fifo,:lu,:ttl,:lirs,:soft, or:basic:threshold— max entries for:lru,:fifo,:lu:ttl— time-to-live in ms for:ttlpolicy:s-history-limit/:q-history-limit— for:lirspolicy
Defaults come from pocket-defaults.edn.
Switch to a FIFO policy with 100 entries:
(pocket/set-mem-cache-options! {:policy :fifo :threshold 100})10:06:47.781 INFO scicloj.pocket - Mem-cache options set: {:policy :fifo, :threshold 100}
10:06:47.781 INFO scicloj.pocket.impl.cache - Mem-cache reconfigured: {:policy :fifo, :threshold 100}
{:policy :fifo, :threshold 100}Reset to default:
(pocket/set-mem-cache-options! {:policy :lru :threshold 256})10:06:47.782 INFO scicloj.pocket - Mem-cache options set: {:policy :lru, :threshold 256}
10:06:47.782 INFO scicloj.pocket.impl.cache - Mem-cache reconfigured: {:policy :lru, :threshold 256}
{:policy :lru, :threshold 256}reset-mem-cache-options!
[]
Reset the in-memory cache configuration to library defaults. Clears any options set by set-mem-cache-options! and reconfigures the mem-cache with the default policy from pocket-defaults.edn. Returns the default options.
Reset mem-cache configuration to library defaults:
(pocket/reset-mem-cache-options!)10:06:47.783 INFO scicloj.pocket - Mem-cache options reset to defaults: {:policy :lru, :threshold 256}
10:06:47.783 INFO scicloj.pocket.impl.cache - Mem-cache reconfigured: {:policy :lru, :threshold 256}
{:policy :lru, :threshold 256}*storage*
Storage policy for cached computations: :mem+disk, :mem, or :none.
:mem+disk(default) — in-memory cache backed by disk persistence:mem— in-memory cache only, no disk I/O:none— no shared cache; instance-local memoization only
Resolved with precedence: binding > set-storage! > POCKET_STORAGE env var > pocket.edn :storage > pocket-defaults.edn (library default: :mem+disk).
set-storage!
[storage]
Set the storage policy by altering *storage*. Valid values: :mem+disk, :mem, :none. Returns the storage policy.
Switch to memory-only storage:
(pocket/set-storage! :mem)10:06:47.784 INFO scicloj.pocket - Storage policy set to: :mem
:memReset to default:
(pocket/set-storage! nil)10:06:47.785 INFO scicloj.pocket - Storage policy set to: nil
nilcleanup!
[]
Delete the cache directory, removing all cached values. Also clears the in-memory cache. Returns a map with :dir and :existed indicating what happened.
(pocket/cleanup!)10:06:47.787 INFO scicloj.pocket - Cache cleanup: /tmp/pocket-demo-reference
{:dir "/tmp/pocket-demo-reference", :existed true}clear-mem-cache!
[]
Clear all entries from the in-memory cache and the origin registry, without deleting the disk cache. The next deref of a cached value will reload from disk if available and re-register origin identity. Useful for testing scenarios that need to simulate memory eviction.
Clear in-memory cache without touching disk:
(deref (pocket/cached #'expensive-calculation 10 20))10:06:47.788 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 10 + 20 (this is expensive!)
30(pocket/clear-mem-cache!)nilinvalidate!
[func & args]
Invalidate a specific cached computation, removing it from both disk and memory. Takes the same arguments as cached: a function var (or keyword) and its arguments. Returns a map with :path and :existed.
Remove a specific cached entry:
(deref (pocket/cached #'expensive-calculation 10 20))30(pocket/invalidate! #'expensive-calculation 10 20)10:06:48.194 INFO scicloj.pocket.impl.cache - Invalidated: /tmp/pocket-demo-reference/a3/(pocket-book.api-reference_expensive-calculation 10 20) existed= true
{:path
"/tmp/pocket-demo-reference/a3/(pocket-book.api-reference_expensive-calculation 10 20)",
:existed true}Derefing again will recompute:
(deref (pocket/cached #'expensive-calculation 10 20))10:06:48.195 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 10 + 20 (this is expensive!)
30invalidate-fn!
[func]
Invalidate all cached entries for a given function var (or keyword), regardless of arguments. Removes matching entries from both disk and memory. Returns a map with :fn-name, :count, and :paths.
Cache a few entries, then invalidate them all:
(deref (pocket/cached #'expensive-calculation 1 2))10:06:48.599 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 1 + 2 (this is expensive!)
3(deref (pocket/cached #'expensive-calculation 3 4))10:06:49.003 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 3 + 4 (this is expensive!)
7(pocket/invalidate-fn! #'expensive-calculation)10:06:49.407 INFO scicloj.pocket.impl.cache - Invalidated 3 entries for pocket-book.api-reference/expensive-calculation
{:fn-name "pocket-book.api-reference/expensive-calculation",
:count 3,
:paths
["/tmp/pocket-demo-reference/a3/(pocket-book.api-reference_expensive-calculation 10 20)"
"/tmp/pocket-demo-reference/d2/(pocket-book.api-reference_expensive-calculation 1 2)"
"/tmp/pocket-demo-reference/49/(pocket-book.api-reference_expensive-calculation 3 4)"]}(pocket/cleanup!)10:06:49.408 INFO scicloj.pocket - Cache cleanup: /tmp/pocket-demo-reference
{:dir "/tmp/pocket-demo-reference", :existed true}cache-entries
[]
[fn-name]
Scan the cache directory and return a sequence of metadata maps. Each entry contains :path, :id, :fn-name, :args-str, and :created-at (when metadata is available — entries cached before metadata support will only have :path). Optionally filter by function name.
List all cached entries:
(deref (pocket/cached #'expensive-calculation 10 20))10:06:49.410 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 10 + 20 (this is expensive!)
30(deref (pocket/cached #'expensive-calculation 3 4))10:06:49.813 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/expensive-calculation
Computing 3 + 4 (this is expensive!)
7(pocket/cache-entries)[{:path
"/tmp/pocket-demo-reference/a3/(pocket-book.api-reference_expensive-calculation 10 20)",
:id "(pocket-book.api-reference/expensive-calculation 10 20)",
:fn-name "pocket-book.api-reference/expensive-calculation",
:args-str "[10 20]",
:created-at "2026-02-09T08:06:49.810916122Z"}
{:path
"/tmp/pocket-demo-reference/49/(pocket-book.api-reference_expensive-calculation 3 4)",
:id "(pocket-book.api-reference/expensive-calculation 3 4)",
:fn-name "pocket-book.api-reference/expensive-calculation",
:args-str "[3 4]",
:created-at "2026-02-09T08:06:50.214225562Z"}]Filter by function name:
(pocket/cache-entries "pocket-book.api-reference/expensive-calculation")[{:path
"/tmp/pocket-demo-reference/a3/(pocket-book.api-reference_expensive-calculation 10 20)",
:id "(pocket-book.api-reference/expensive-calculation 10 20)",
:fn-name "pocket-book.api-reference/expensive-calculation",
:args-str "[10 20]",
:created-at "2026-02-09T08:06:49.810916122Z"}
{:path
"/tmp/pocket-demo-reference/49/(pocket-book.api-reference_expensive-calculation 3 4)",
:id "(pocket-book.api-reference/expensive-calculation 3 4)",
:fn-name "pocket-book.api-reference/expensive-calculation",
:args-str "[3 4]",
:created-at "2026-02-09T08:06:50.214225562Z"}]cache-stats
[]
Return aggregate statistics about the cache. Returns a map with :total-entries, :total-size-bytes, and :entries-per-fn.
(pocket/cache-stats){:total-entries 2,
:total-size-bytes 388,
:entries-per-fn {"pocket-book.api-reference/expensive-calculation" 2}}(pocket/cleanup!)10:06:50.223 INFO scicloj.pocket - Cache cleanup: /tmp/pocket-demo-reference
{:dir "/tmp/pocket-demo-reference", :existed true}origin-story
[x]
Given a value, return its computation DAG as a nested map.
For a Cached value, each node is {:fn <var> :args [<nodes>] :id <string>}, with :value included if the computation has been realized. Plain (non-Cached) arguments become {:value <val>} leaf nodes.
When the same Cached instance appears multiple times in the tree, subsequent occurrences are represented as {:ref <id>} pointing to the first occurrence’s :id. This enables proper DAG representation for diamond dependencies.
Does not trigger computation — only peeks at already-realized values. Works with all storage policies (:mem+disk, :mem, :none).
origin-story returns a nested map describing a computation’s DAG. Each cached step is {:fn <var> :args [...]}, with :value if realized. Plain arguments become {:value ...} leaves.
(defn step-a [x] (+ x 10))(defn step-b [x y] (* x y))(def a-c (pocket/cached #'step-a 5))(def b-c (pocket/cached #'step-b a-c 3))Before deref — no :value keys:
(pocket/origin-story b-c){:fn #'pocket-book.api-reference/step-b,
:args
[{:fn #'pocket-book.api-reference/step-a,
:args [{:value 5}],
:id "c2"}
{:value 3}],
:id "c1"}Deref to trigger computation:
(deref b-c)10:06:50.228 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/step-b
10:06:50.228 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/step-a
45After deref — :value keys appear:
(pocket/origin-story b-c){:fn #'pocket-book.api-reference/step-b,
:args
[{:fn #'pocket-book.api-reference/step-a,
:args [{:value 5}],
:id "c2",
:value 15}
{:value 3}],
:id "c1",
:value 45}origin-story-mermaid
[x]
Given a value, return a Mermaid flowchart string of its computation DAG.
Accepts a Cached value (walks it via origin-story) or a tree map previously returned by origin-story.
Returns a plain string. Wrap with (kind/mermaid ...) for Kindly rendering.
Returns a Mermaid flowchart with kindly metadata for notebook rendering:
(pocket/origin-story-mermaid b-c)origin-story-graph
[x]
Given a value, return its computation DAG as a normalized graph.
Returns {:nodes {<id> <node-map>} :edges [[<from> <to>] ...]}.
Node maps contain :fn (for cached steps) or :value (for leaves), plus :value if the cached computation has been realized.
This is the fully normalized (Format B) representation of the DAG. Use origin-story for the tree-with-refs representation (Format A).
origin-story-graph returns a normalized {:nodes ... :edges ...} format, suitable for graph algorithms:
(pocket/origin-story-graph b-c){:nodes
{"c1" {:fn #'pocket-book.api-reference/step-b, :value 45},
"c2" {:fn #'pocket-book.api-reference/step-a, :value 15},
"v3" {:value 5},
"v4" {:value 3}},
:edges [["c1" "c2"] ["c2" "v3"] ["c1" "v4"]]}compare-experiments
[cached-values]
Compare multiple cached experiment results.
Takes a seq of Cached values (typically final metrics from different hyperparameter configurations). Walks each experiment’s origin-story to extract parameter maps, identifies which parameters vary across experiments, and returns a seq of maps containing the varying params plus the experiment result.
Only parameters that differ across experiments are included. The :result key contains the derefed value of each Cached.
compare-experiments extracts varying parameters from multiple experiments. This is useful for hyperparameter sweeps where you want to see which parameters differ across experiments.
(defn run-exp [config]
{:rmse (* 0.1 (:lr config))})(def exp1 (pocket/cached #'run-exp {:lr 0.01 :epochs 100}))(def exp2 (pocket/cached #'run-exp {:lr 0.001 :epochs 100}))(pocket/compare-experiments [exp1 exp2])10:06:50.237 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/run-exp
10:06:50.238 INFO scicloj.pocket.impl.cache - Cache miss, computing: pocket-book.api-reference/run-exp
[{:lr 0.01, :result {:rmse 0.001}} {:lr 0.001, :result {:rmse 1.0E-4}}]Note: :epochs is not shown because it’s the same (100) in both experiments. Only varying parameters appear in the comparison.
(pocket/cleanup!)10:06:50.242 INFO scicloj.pocket - Cache cleanup: /tmp/pocket-demo-reference
{:dir "/tmp/pocket-demo-reference", :existed true}Extending PIdentifiable
You can customize how your types contribute to cache keys by extending the PIdentifiable protocol. See the Extending Pocket chapter for a full walkthrough with examples.