Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial vs function literal when memoize

This is giving me a bit of brain thump:

user> (repeatedly 10 #((memoize rand-int) 10))
(7 0 4 8 1 2 2 1 6 9)
user> (repeatedly 10 (partial (memoize rand-int) 10))
(8 8 8 8 8 8 8 8 8 8)

I would like to know if the reason for this is because the function literal (first version) is called/evaluated every time, thus the memoize is "recreated" (re-memorized) each time, therefore not really having any true meaningful "memorization" at all, while the second one with partial is actually returning a fixed function that is evaluated just once, where the same value of memoize is thus used every time (sort of like a closure though I don't think this qualifies as a true "closure")

Am I thinking correctly?

like image 373
johnbakers Avatar asked Jan 05 '14 08:01

johnbakers


People also ask

Is Memoization the same as caching?

Is memoization same as caching? Yes, kind of. Memoization is actually a specific type of caching. While caching can refer in general to any storing technique (like HTTP caching) for future use, memoizing specifically involves caching the return values of a function .

What is a Memoized function?

Memoization: Memoization is a technique for speeding up applications by caching the results of expensive function calls and returning them when the same inputs are used again.

What is Lodash Memoize?

memoize(func, [resolver]) Creates a function that memoizes the result of func. If resolver is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key.


1 Answers

Yes, memoize doesn't modify its argument in any way, so

#((memoize rand-int) 10)

recreates the memoized function on each call.

(fn [] ((memoize rand-int) 10))

is equivalent.

To call a memoized function from another function, you need to put it in a Var or a closed-over local:

(repeatedly 10 (let [r (memoize rand-int)] #(r 10)))
;= (2 2 2 2 2 2 2 2 2 2)

In the partial example, the function returned by (memoize rand-int) is passed as an argument to the function partial, which then returns a closure which closes over the return of (memoize rand-int). So, this is very close to the example above (except the closure returned by partial uses apply to call the memoized function).

like image 160
Michał Marczyk Avatar answered Oct 02 '22 20:10

Michał Marczyk