Renzo Borgatti
unread,Feb 4, 2013, 5:06:06 AM2/4/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to sic...@googlegroups.com
Here's the note from last in-person book club, Thu 31st.
We were just 3 of us and I proposed a little exercise that I was doing on my own as part of the assignment. My goal was the following: test drive the iterative solution of 1.11 and it turned out to be an exceptional learning experience on how to take requirements for an iterative function and transform them into working code. Basically, you work your way bottom up (at least this was easier for me) discovering how a function "f" that should carry state each time is called should behave:
(facts "when >= 3"
(fact "for n=3, it sums up f(2), two times f(1) and three times f(0)"
(f 2 1 0 3) => (+ 2 2 0))
(fact "for n=4, it sums up f(3), two times f(2) and three times f(1)"
(f 2 1 0 4) => (+ 4 4 3))
(fact "for n=5, it sums up f(4), two times f(3) and three times f(2)"
(f 2 1 0 5) => (+ 11 8 6))
(fact "for n=6, it sums up f(5), two times f(4) and three times f(3)"
(f 2 1 0 6) => (+ 25 22 12)))
As you can see "f" first three arguments are always the same, 2-1-0, corresponding to the base case (n<3) while the last argument is acting as a counter for how many times the internal computation should be repeated. The implementation for those tests goes something like:
(defn f [times-one times-two times-three counter]
(if (< counter 3)
times-one
(f (+ (* 1 times-one) (* 2 times-two) (* 3 times-three)) times-one times-two (- counter 1))))
But our requirements are a function that takes one argument only, like (f-recur 4), so we need another set of tests for that:
(facts "when >= 3 I can just pass in the single number"
(fact "for n=3, it sums up f(2), two times f(1) and three times f(0)"
(f-recur 3) => (+ 2 2 0))
(fact "for n=4, it sums up f(3), two times f(2) and three times f(1)"
(f-recur 4) => (+ 4 4 3)))
They are the same as before, really. Our goal for the implementation is to re-use our "f" we specified earlier, and we know the first 3 args are always the same:
(defn f-recur [n]
(if (< n 3)
n
(f 2 1 0 n)))
It was not as easy as described here. In particular at some point I had to write the solution as a big step, without finding the corresponding "baby" steps for a proper TDD practice. After looking at the final solution I was able to see the proper TDD steps backward. Sometimes this is the only way to understand ;)
Going to check-in everything into github.
Cheers
Renzo