Skip to content

Commit 0183ca2

Browse files
Added the memoize core fn (#813)
Hi, could you please consider an implementation of the `memoize` core fn. It fixes #812. Also added some basic tests. Thanks Co-authored-by: ikappaki <[email protected]> Co-authored-by: Chris Rink <[email protected]>
1 parent d08ac3d commit 0183ca2

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Added support for autocompleting names in the `python/` pseudo-namespace for Python builtins at the REPL (#787)
1313
* Added a subcommand for bootstrapping the Python installation with Basilisp (#790)
1414
* Added support for executing Basilisp namespaces directly via `basilisp run` and by `python -m` (#791)
15+
* Added the `memoize` core fn (#812)
1516

1617
### Changed
1718
* Optimize calls to Python's `operator` module into their corresponding native operators (#754)

src/basilisp/core.lpy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3321,6 +3321,19 @@
33213321
(concat '(fn* []) [expr]))
33223322
exprs)))
33233323

3324+
(defn memoize
3325+
"Retuns a fn that caches the results of the previous invocations of
3326+
`f`. The memoized fn keeps a cache of the mapping from arguments to
3327+
results."
3328+
[f]
3329+
(let [cache (atom {})]
3330+
(fn [& args]
3331+
(if-let [kv (find @cache args)]
3332+
(second kv)
3333+
(let [res (apply f args)]
3334+
(swap! cache assoc args res)
3335+
res)))))
3336+
33243337
;;;;;;;;;;;;;;;;;;;;;;
33253338
;; Random Functions ;;
33263339
;;;;;;;;;;;;;;;;;;;;;;

tests/basilisp/prompt_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def patch_completions(self, completions: Iterable[str]):
7575
"max",
7676
"max-key",
7777
"memfn",
78+
"memoize",
7879
"merge",
7980
"meta",
8081
"methods",

tests/basilisp/test_core_fns.lpy

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,29 @@
10821082
'(((1 2 (3)) (4)) (1 2 (3)) 1 2 (3) 3 (4) 4) seq? identity '((1 2 (3)) (4))
10831083
'((:A (:B (:D) (:E)) (:C (:F))) (:B (:D) (:E)) (:D) (:E) (:C (:F)) (:F)) next rest '(:A (:B (:D) (:E)) (:C (:F)))))
10841084

1085+
(deftest memoize-test
1086+
(testing "single args"
1087+
(let [m1 (memoize (fn [a] (str a (random-uuid))))
1088+
a1 (m1 :a)
1089+
a2 (m1 :b)
1090+
an (m1 nil)]
1091+
(is (= a1 (m1 :a)))
1092+
(is (= a2 (m1 :b)))
1093+
(is (= an (m1 nil)))
1094+
(is (distinct? a1 a2 an))))
1095+
1096+
(testing "variadic"
1097+
(let [m1 (memoize (fn [& more] (str more (random-uuid))))
1098+
a0 (m1)
1099+
a1 (m1 :a)
1100+
a2 (m1 :a '(xyz))
1101+
an (m1 nil)]
1102+
(is (= a0 (m1)))
1103+
(is (= a1 (m1 :a)))
1104+
(is (= a2 (m1 :a '(xyz))))
1105+
(is (= an (m1 nil)))
1106+
(is (distinct? a0 a1 a2 an)))))
1107+
10851108
;;;;;;;;;;;;;;;;;;;;;;;;;;;
10861109
;; Associative Functions ;;
10871110
;;;;;;;;;;;;;;;;;;;;;;;;;;;

0 commit comments

Comments
 (0)