countvajhula · GitHub

Macro

(define-syntax-parameter break
  (lambda (stx)
    (raise-syntax-error (syntax-e stx) "can only be used inside `while`")))
(define-syntax-parse-rule (while condition body ...)
  (call/ec
   (λ (return)
     (syntax-parameterize ([break (make-rename-transformer #'return)])
       (let loop ()
         (when condition
           (begin body ...
                  (loop))))))))

This uses an escape continuation to provide the semantics of break, and leverages it using a syntax parameter so that the continuation is accessible in the lexical scope of the while body, and also so that break is a syntax error outside the while loop.

Example

(define x 5)
(while (> x 0)
  (displayln x)
  (set! x (sub1 x)))
(set! x 5)
(while #t
  (displayln x)
  (set! x (sub1 x))
  (unless (> x 0)
    (break)))

Licence

This code and all associated text involved in this submission is released as public domain.

Read the original on github.com ↗