I would like to add a counter so I can see how many times the iteration runs:
(define tolerance 0.01)
(define (close-enough? x y) (< (abs (- x y)) 0.001))
(define (fixed-point function starting-guess)
(define iter-count 0)
(define (evaluate num)
; these lines increment the counter using set!
(set! iter-count (+ iter-count 1))
(display iter-count) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
(fixed-point cos 1.0)
What would be the proper way to do this? Currently I have added in a define
and a set!
as I couldn't figure out a way to get let
to work. Is there a way to do this with let
, or what's the suggested way to do this?
Or, I suppose another way is to pass it as a parameter to the iteration function itself:
(define (fixed-point function starting-guess)
(define (evaluate num iteration-num)
(display iteration-num) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ 1 iteration-num)))))
(evaluate starting-guess 0))
Just like num
you just add it a a parameter to your loop function:
(define (fixed-point function starting-guess)
;; prints progress
(define (print-progress iter-count)
(display iter-count)
(display " - ")
(display num)
(newline))
;; main calculating loop
(define (evaluate num iter-count)
(print-progress iter-count)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ iter-count 1)))))
;; start process with iter-count 1 since
;; we do increments after display
(evaluate starting-guess 1))
Notice that your version of this started displaying 0
while your set!
version started with 1
. I compensated for this by starting off with 1
instead of 0
.
You could keep the side effects away from fixed-point
completely by adding the functionality to the function
:
;; pure functional fixed-point
(define (fixed-point function starting-guess)
(define (evaluate num)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
;; makes a version of function that
;; reports its first argument and
;; number of times it's been called
(define (count-and-brag-calls f)
;; brag does whatever and
;; return the value
(define (brag v c)
(display c)
(display " - ")
(display v)
(newline)
v)
;; actual implementation
(let ((count 0))
(lambda (n)
(set! count (+ count 1))
(brag (f n) count))))
;; with verbose output
(fixed-point (count-and-brag-calls cos) 1.0)
;; without side effects gives exact same result without output
(fixed-point cos 1.0)