1 Posts Tagged 'SICP'
Functional programming hurts me
This post will probably come back to haunt me, but functional programming doesn't sit well with me. I'm trying again to read through SICP. Last time I tried, I lost track of it and gave up after a few chapters. This time I hope to persevere, and I'm trying to go more slowly through the examples to really understand things.
I was trying to do some of the exercises in chapter 1 today, and pretty much bombing on all of them. Most of the exercises I've seen so far in SICP sound like they came out of a math book. "There is a clever algorithm for computing the Fibonacci numbers in a logarithmic number of steps..." Uh huh. This is not the kind of problem I enjoy, or have even the slightest use for. But maybe the problems are only pointless examples to illustrate a point, like "mass-less friction-less pulleys" in physics textbooks. I can live with that I guess.
Here is a Scheme example from SICP to compute b to the power of n:
(define (expt b n)
(expt-iter b n 1))
(define (expt-iter b counter product)
(if (= counter 0)
product
(expt-iter b
(- counter 1)
(* b product))))
This is presented as a wonderful and novel functional programming approach.
One of my problems is the amount of brain-work it takes to understand this. OK, start with EXPT. We take b and n, and then call some recursive helper function with b, n, and a state variable product initialized to 1 HEY WAIT A SECOND THERE'S A STATE VARIABLE?!
This is one way to cheat in functional programming, I guess. product is a variable name / symbol, which describes "something" that takes on different values over time, each value representing the same "thing" in different states. That qualifies as a state variable to me. The only difference is that the state variable is actually N different variables (with the same name) splattered across a bunch of frames on a call stack, instead of an abstraction of a single simple bucket where I dump a value.
Now in EXPT-ITER, counter starts at n, and every time the function calls itself, counter decreases by 1, until you reach 0, at which point EXPT-ITER stops calling itself and returns something. So this is a perverted, inside-out way of saying "do something N times", where every iteration costs me a recursive function call. Nice.
OK, what are we doing N times? We're multiplying product, which starts at 1, by b, which then becomes the new value of product next time around.
SO WHY NOT JUST WRITE THAT TO BEGIN WITH?
(defun simple-expt (b n)
(let ((total 1))
(dotimes (i n)
(setf total (* total b)))
total))
In Common Lisp this reads as "Let total start at 1. N times, set total to the product of total and b. Then return total." This is EXACTLY what the Scheme version is doing. Except I don't have to turn my brain inside-out to write it down this way. The CL code reads exactly like what the program is doing.
When all you have is a hammer, every problem looks like a nail. When all you have is recursion, every problem looks like it should be solved using recursion, I guess.
Actually if I ignore the functional programming bits, SICP is a great book. There are a lot of good things in there. But (so far) Scheme isn't one of them.
