Flow-control structures: Difference between revisions

Line 1,393:
 
=={{header|Racket}}==
 
...
=== exit ===
Racket's <tt>exit</tt> quits the whole process, optionally returning an exit code. Note that there is an <tt>exit-handler</tt> that can be set to intercept such exit attempts.
 
=== goto ===
Racket doesn't have a <tt>goto</tt>, but like other implementations of Scheme, it adopts the mantra of "Lambda: the Ultimate GOTO" by having all tail calls optimized. This allows writing code that is no different from your average assembly code -- for example, here's a direct translation of [[Greatest_common_divisor#x86_Assembly]] into a Racket function:
 
<lang racket>
#lang racket
 
;; some silly boilerplate to mimic the assembly code better
(define r0 0)
(define (cmp r1 r2) (set! r0 (sgn (- r1 r2))))
(define (je true-label false-label) (if (zero? r0) (true-label) (false-label)))
(define (goto label) (label))
 
(define (gcd %eax %ecx)
(define %edx 0)
(define (main) (goto loop))
(define (loop) (cmp 0 %ecx)
(je end cont))
(define (cont) (set!-values [%eax %edx] (quotient/remainder %eax %ecx))
(set! %eax %ecx)
(set! %ecx %edx)
(goto loop))
(define (end) (printf "result: ~s\n" %eax)
(return %eax))
(main))
</lang>
 
=== Exceptions ===
 
Racket has exceptions which are used in the usual way, and <tt>with-handlers</tt> to catch them. In fact, any value can be raised, not just exceptions. For example:
 
<lang racket>
(define (list-product l)
(with-handlers ([void identity])
(let loop ([l l] [r 1])
(cond [(null? l) r]
[(zero? (car l)) (raise 0)]
[else (loop (cdr l) (* r (car l)))]))))
</lang>
 
=== Continuations ===
 
Racket has full continuations, of all kinds, including delimited and not. That's plenty of control flow...
 
=== And more ===
 
Given that Racket has macros, and continuations, and a zillion other features, it is easy to implement
new control flow expressions, so any list will not be exhaustive.
 
=={{header|REBOL}}==