summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Orst <andreyorst@gmail.com>2020-11-13 18:59:53 +0300
committerAndrey Orst <andreyorst@gmail.com>2020-11-13 18:59:53 +0300
commit8493fa29b1848bf93e899e8930c6e8c1c723eece (patch)
treea593eebee78f37a06ebd8e38901e0303dd9519f0
parente7bfab5be155878b9850e6c5986631133aa866c1 (diff)
feature(core): add memoize function
TODO: Wonder how to test it...
-rw-r--r--cljlib.fnl19
1 files changed, 19 insertions, 0 deletions
diff --git a/cljlib.fnl b/cljlib.fnl
index 3ddaf3f..866ece5 100644
--- a/cljlib.fnl
+++ b/cljlib.fnl
@@ -617,4 +617,23 @@ that would apply to that value, or `nil' if none apply and no default."
([x y & xs]
(reduce #(and $1 $2) (eq x y) (mapv #(eq x $) xs))))
+(fn& core.memoize [f]
+ "Returns a memoized version of a referentially transparent function.
+The memoized version of the function keeps a cache of the mapping from
+arguments to results and, when calls with the same arguments are
+repeated often, has higher performance at the expense of higher memory
+use."
+ (let [memo (setmetatable {} {:__index
+ (fn [tbl key]
+ (each [k v (pairs tbl)]
+ (when (eq k key)
+ (lua "return v"))))})]
+ (fn [...]
+ (let [args [...]]
+ (if-some [res (. memo args)]
+ res
+ (let [res (f ...)]
+ (tset memo args res)
+ res))))))
+
core