Caching

headmastersquall edited this page Dec 29, 2014 · 4 revisions
Clone this wiki locally

Suppose that you want to check whether a function is properly memoized, such that it doesn't execute the second time it's called. You can do that by specifying a zero call count:

      (unfinished called-function)

      (def myfun (memoize (fn [n] (+ 500 (expensive-calculation n)))))

      (fact "First use causes calculation"
        (myfun 3) => 503
        (provided (expensive-calculation 3) => 3))

      (fact "Second use uses cache"
        (myfun 3) => 503
        (provided (expensive-calculation anything) => anything :times 0))

That's annoyingly indirect: you're checking that the function is not being called by checking that it in turn doesn't call what it otherwise would. If you're willing to use two names for the function and an atypical memoization, you could instead do this:

     (defn myfun-uncached [n] (+ 500 n))
     (def myfun (memoize #'myfun-uncached))  ; <= important

     (fact "First use causes calculation"
       (myfun 3) => 503
       (provided (myfun-uncached 3) => 503))

     (fact "Second use uses cache"
       (myfun 3) => 503
       (provided (myfun-uncached anything) => anything :times 0))

The line marked important highlights that you need to memoize the var you call through, not the functional value itself. If you just wrote (memoize myfun-uncached), Midje wouldn't be able to intercept the call.