I was working through a problem at Programming Praxis<http://programmingpraxis.com/2009/12/18/calculating-logarithms/>, and was happy to find that my solution closely matched the "approved" solution, but I noted a fairly big difference in our styles, and I thought I'd seek the community's feedback...
To illustrate, I present part of the problem, that solves for square roots by recursion using Newton's method: x <- x - (y - x^2)/2x I now show the "approved" solution, and my own, both edited a bit to cleanly present my questions. (define epsilon 1e-7) ; The "approved" solution (define (approved-sqrt y) (let loop [(x (/ y 2))] (if (< (abs (- (* x x) y)) epsilon) x (loop (- x (/ (- (* x x) y) (+ x x))))))) ; My solution (define (my-sqrt y) (let loop [(x (/ y 2))] (let [(error (- y (* x x)))] (if (< (abs error) epsilon) x (loop (+ x (/ error 2 x))))))) I haven't timed the two, as I'm more interested in the "big picture" than this particular function. Question 1: Is my use of the temporary "error" worth it in terms of performance (the approved solution calculates (* x x) twice)? If it's not worth it, how big does the calculation have to become before it does? Can the compiler make such a temporary live only in a register? Question 1a: How creeped are you by my changing the meaning of error for these few lines? I find myself doing stuff like this, in the name of my idea of readability, a lot. Question 2: The approved solution favored (/ ... (+ x x)) over my (/ ... 2 x). Cost of division versus readability. Wasn't a conscious decision of mine at the time, but now I'm curious. How smart is the compiler when presented with a division by 2? With multiple recalls of the same value? Thanks for any comments. Pat
_________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users