Search code examples
recursionschemeracketsequenceapproximation

Coding an approximation sequence recursively. DrRacket, Scheme


Very recently, a question was asked, "How to find mistake in my sequence. DrRacket, Scheme", and then deleted by an impatient asker.

Since I was in the process of typing the very few last words of my answer, here it is reposted, the Q and the A, so that it won't go to waste.

Here it is quoted almost verbatim:


I am trying to solve this sequence:

enter image description here

I am doing it in a do loop, the condition of stop-expression is

enter image description here

But my do loop doesn't work. I can't find a mistake. Please, help me. My code:

(define (y a n x )
  (if (= n 0)
  a
  (* 0.5 (+ (y a (- n 1) x) (/ x (y a (- n 1) x))))
  )
  )
(define (f a x e)

 (do
  ( (n 0 (+ n 1)) )  


( ( < (abs (- (sqr (y a n x)) (sqr (y a (- n 1) x)))) e) ("end of loop")) 

(display (y a n x))
(newline)

)
 )

Solution

  • Indentation is your friend, not your enemy:

    (define (y a n x)
      (if (= n 0)
        a
        (* 0.5 (+      (y a (- n 1) x) 
                  (/ x (y a (- n 1) x)) )) ))
    
    (define (f a x e)    
      (do ( (n 0 (+ n 1)) )  
          ( (< (abs (- (sqr (y a    n    x)) 
                       (sqr (y a (- n 1) x)) ))
               e) 
            ("end of loop")) 
        (display (y a n x))
        (newline)))
    

    This code is pretty unusual in its approach. It reminds of iterative deepening in Prolog. You are trying to solve it in gradually increasing number of steps.

    Put differently, you calculate the nth and the (n-1)th member of the sequence in isolation. But really, it takes just one step to go from the latter to the former.


    Here is the situation where recursion is not your friend.

    Corecursion, i.e. iteration, is your friend here.

    Instead of counting from n down to 0 on each step, while incrementing the starting value of n before each step all the time;

    0
    1 0
    2 1 0
    3 2 1 0
    ....
    

    why not just simply count up, from 0, in increments of 1:

    0 1 2 3 ....
    

    going boldly forward until the condition holds?

    But what do we care how many steps did it take to reach the solution? We don't! We don't need n at all.

    Not to mention that (- 0 1) is a value which your function y is forced to deal with, by the do loop in f, yet is not equipped to handle, leading to bottomless recursion. And that's just the one issue that jumped at me from your code; there's more (a string is not a function), but really, the code needs to be overhauled anyway.