#lang scheme/base (provide until while) #| Loops Repeating Statements by Condition. Two types of effect of the condition. (while <pre-condition> . _): continue if precondition true (until <post-condition> . _): break out if postcondition true An 'until' loop has a value: the logically positive value of the postcondition. Commonest form of compound condition. (while (and <pre-condition> ...) . _): continue if all preconditions true (until (or <post-condition> ...) . _): break out if some postcondition true, with that postcondition's value Post-processing based on which subcondition of compound condition ended loop: (while (and (<pre-condition> else <result> ...) ...) . _) (until (or (<post-condition> then <result> ...) ...) . _) Value of loop is value of <result> ... . |# (define-syntax until (syntax-rules (or then) [(until (or (<post-condition> then <result> ...) ...) <statement> ...) (let/cc result (letrec ([loop (λ () (cond [<post-condition> (result (let () <result> ...))] ... [else <statement> ... (loop)]))]) (loop)))] [(until <post-condition> <statement> ...) (letrec ([loop (λ () (unless <post-condition> <statement> ... (loop)))]) (loop))])) (define-syntax while (syntax-rules (and else) [(while (and (<pre-condition> else <result> ...) ...) <statement> ...) (until (or ((not <pre-condition>) then <result> ...) ...) <statement> ...)] [(while <pre-condition> <statement> ...) (until (not <pre-condition>) <statement> ...)]))