I've been off work ill today, but reading was getting on my nerves, so I decided to do more work in scala, and wrote some objects to do easy Memoization. I thought I needed them to optimise something else that I was doing, then found a better way to do it without classical memoization (sigh).
The code was heavily based on something I found here (hat tip michid), with minor tweaks of my own. Here's how you use the memo classes anyway:
scala> import com.uncarved.helpers.Memoize
scala> val circArea =
| Memoize((r:Double)=>Math.Pi * Math.pow(r,2))
circArea: com.uncarved.helpers.Memoize.MemoizedFunction1[Double,Double] = <function>
scala> val area = circArea(2)
area: Double = 12.566370614359172
So you can use something like a function and it seems to do the right thing. "But how", you may well ask, "do I know it's actually memoizing and this isn't all a big trick?". A fair and honest question. We need to add a function that has a side-effect so we can demonstrate that it is in fact doing the right thing.
We need a function that will print something to the terminal when the calculation is actually invoked. When it isn't, it will return the same result, but without any printing.
scala> val cylVol = Memoize {
| (r:Double, h:Double) =>
| val vol = Math.Pi * Math.pow(r,2) * h
| println("Radius: " + r + " Height: " +
| h + " Volume: " + vol)
| vol
| }
cylVol: com.uncarved.helpers.Memoize.MemoizedFunction2[Double,Double,Double] = <function>
The first time we invoke our function it hits the print statement:
scala> cylVol(3,4.5)
Radius: 3.0 Height: 4.5 Volume: 127.23450247038662
res1: Double = 127.23450247038662
...but when we invoke the function again on identical arguments, the cached result is used, so we don't see the print.
scala> cylVol(3,4.5)
res2: Double = 127.23450247038662
If the arguments change, a fresh invocation is made.
scala> cylVol(3,4)
Radius: 3.0 Height: 4.0 Volume: 113.09733552923255
res3: Double = 113.09733552923255
You can get the code and libs by using sbaz to update your uncarved-helpers package, or just via the tarball. For the curious, here's the full text of the scala code.
Unless otherwise specified the contents of this page are copyright © 2015 Sean Hunter. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.