schemeracket

Using break from loop in Racket


I can use "while" loop in Racket with code from While Loop Macro in DrRacket

(define-syntax-rule (while-loop condition body ...)   
  (let loop ()
    (when condition
      body ...
      (loop))))

However, I want to use break inside an infinite loop as follows:

(define (testfn)
  (define x 5)
  (while-loop #t          ; infinite while loop; 
    (println x)
    (set! x (sub1 x))
    (when (< x 0)
       (break))))         ; HOW TO BREAK HERE; 

How can I insert break in above indefinite while loop? Thanks for your comments/answers.


Solution

  • You don't. Racket is in the Scheme family so all loops are actually done with recursion.

    You break out of a loop by not recursing. Any other value would become the result of the form.

    (define (helper x) 
      (displayln x) 
      (if (< x 0)
          'return-value
          (helper (sub1 x))) 
    (helper 5)
    

    There are macros that makes the syntax simpler. Using named let is one:

    (let helper ((x 5))
      (displayln x) 
      (if (< x 0)
          'return-value
          (helper (sub1 x)))
    

    Looking at your while-loop is just a macro that uses named let macro that turns into a recursive procedure.

    If you instead of #t write an expression that eventually becomes false it stops. Like:

    (while-loop (<= 0 x)
      ...)
    

    Note that using set! to update variables in a loop is not considered good practise. If you are learning Racket try not to use set! or your new looping construct. Try using named let or letrec.