rnso
rnso

Reputation: 24535

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.

Upvotes: 4

Views: 5798

Answers (2)

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 235994

As mentioned in the accepted answer to the linked question, it's not recommended - at all! to do looping in this fashion. When using standard Scheme avoid imperative loops and prefer recursion (using helper procedures or a named let), or use iterations and comprehensions in Racket.

Also, break is not a standard Scheme construct. Consider rewriting the logic using a more idiomatic Racket that doesn't require explicit breaking and avoids the imperative style:

(define (testfn n)
  (for [(x (in-range n -1 -1))]
    (println x)))

(testfn 5)
=> 5
   4
   3
   2
   1
   0

Upvotes: 3

Sylwester
Sylwester

Reputation: 48745

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.

Upvotes: 8

Related Questions