| 1 | ;; Memoize any function. |
| 2 | |
| 3 | ;; Implement `memoize` using an atom (`mem`) which holds the memoized results |
| 4 | ;; (hash-map from the arguments to the result). When the function is called, |
| 5 | ;; the hash-map is checked to see if the result for the given argument was already |
| 6 | ;; calculated and stored. If this is the case, it is returned immediately; |
| 7 | ;; otherwise, it is calculated and stored in `mem`. |
| 8 | |
| 9 | ;; For recursive functions, take care to store the wrapper under the |
| 10 | ;; same name than the original computation with an assignment like |
| 11 | ;; `(def! f (memoize f))`, so that intermediate results are memorized. |
| 12 | |
| 13 | ;; Adapted from http://clojure.org/atoms |
| 14 | |
| 15 | (def! memoize |
| 16 | (fn* [f] |
| 17 | (let* [mem (atom {})] |
| 18 | (fn* [& args] |
| 19 | (let* [key (str args)] |
| 20 | (if (contains? @mem key) |
| 21 | (get @mem key) |
| 22 | (let* [ret (apply f args)] |
| 23 | (do |
| 24 | (swap! mem assoc key ret) |
| 25 | ret)))))))) |
| 26 | |
| 27 | nil |