This chapter describes various primitive procedures which control the
flow of program execution in special ways.
The procedure?
predicate is also described here.
procedure? obj | procedure |
Returns #t if obj is a procedure, otherwise returns #f. (procedure? car) ==> #t (procedure? 'car) ==> #f (procedure? (lambda (x) (* x x))) ==> #t (procedure? '(lambda (x) (* x x))) ==> #f (call-with-current-continuation procedure?) ==> #t |
apply proc arg1 ... args | procedure |
Proc must be a procedure and args must be a list.
Calls proc with the elements of the list
(apply + (list 3 4)) ==> 7 (define compose (lambda (f g) (lambda args (f (apply g args))))) ((compose sqrt *) 12 75) ==> 30 |
map proc list1 list2 ... | library procedure |
The lists must be lists, and proc must be a
procedure taking as many arguments as there are lists
and returning a single value. If more
than one list is given, then they must all be the same length.
(map cadr '((a b) (d e) (g h))) ==> (b e h) (map (lambda (n) (expt n n)) '(1 2 3 4 5)) ==> (1 4 27 256 3125) (map + '(1 2 3) '(4 5 6)) ==> (5 7 9) (let ((count 0)) (map (lambda (ignored) (set! count (+ count 1)) count) '(a b))) ==> (1 2) or (2 1) |
for-each proc list1 list2 ... | library procedure |
The arguments to (let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v) ==> #(0 1 4 9 16) |
force promise | library procedure |
Forces the value of promise (see (force (delay (+ 1 2))) ==> 3 (let ((p (delay (+ 1 2)))) (list (force p) (force p))) ==> (3 3) (define a-stream (letrec ((next (lambda (n) (cons n (delay (next (+ n 1))))))) (next 0))) (define head car) (define tail (lambda (stream) (force (cdr stream)))) (head (tail (tail a-stream))) ==> 2
(define count 0) (define p (delay (begin (set! count (+ count 1)) (if (> count x) count (force p))))) (define x 5) p ==> a promise (force p) ==> 6 p ==> a promise, still (begin (set! x 10) (force p)) ==> 6 Here is a possible implementation of (define force (lambda (object) (object))) We define the expression (delay <expression>) to have the same meaning as the procedure call (make-promise (lambda () <expression>)) as follows (define-syntax delay (syntax-rules () ((delay expression) (make-promise (lambda () expression))))), where (define make-promise (lambda (proc) (let ((result-ready? #f) (result #f)) (lambda () (if result-ready? result (let ((x (proc))) (if result-ready? result (begin (set! result-ready? #t) (set! result x) result))))))))
Rationale:
A promise may refer to its own value, as in the last example above.
Forcing such a promise may cause the promise to be forced a second time
before the value of the first force has been computed.
This complicates the definition of
Various extensions to this semantics of
|
call-with-current-continuation proc | procedure |
Proc must be a procedure of one
argument. The procedure The escape procedure accepts the same number of arguments as the continuation to
the original call to call-with-current-continuation.
Except for continuations created by the The escape procedure that is passed to proc has unlimited extent just like any other procedure in Scheme. It may be stored in variables or data structures and may be called as many times as desired. The following examples show only the most common ways in which
(call-with-current-continuation (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) '(54 0 37 -3 245 19)) #t)) ==> -3 (define list-length (lambda (obj) (call-with-current-continuation (lambda (return) (letrec ((r (lambda (obj) (cond ((null? obj) 0) ((pair? obj) (+ (r (cdr obj)) 1)) (else (return #f)))))) (r obj)))))) (list-length '(1 2 3 4)) ==> 4 (list-length '(a b . c)) ==> #f Rationale: |
values obj ... | procedure |
Delivers all of its arguments to its continuation.
Except for continuations created by the (define (values . things) (call-with-current-continuation (lambda (cont) (apply cont things)))) |
call-with-values producer consumer | procedure |
Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments. The continuation for the call to consumer is the continuation of the call to call-with-values. (call-with-values (lambda () (values 4 5)) (lambda (a b) b)) ==> 5 (call-with-values * -) ==> -1 |
dynamic-wind before thunk after | procedure |
Calls thunk without arguments, returning the result(s) of this call.
Before and after are called, also without arguments, as required
by the following rules (note that in the absence of calls to continuations
captured using
If a second call to If a second call to If invoking a continuation requires calling the before from one call
to The effect of using a captured continuation to enter or exit the dynamic extent of a call to before or after is undefined. (let ((path '()) (c #f)) (let ((add (lambda (s) (set! path (cons s path))))) (dynamic-wind (lambda () (add 'connect)) (lambda () (add (call-with-current-continuation (lambda (c0) (set! c c0) 'talk1)))) (lambda () (add 'disconnect))) (if (< (length path) 4) (c 'talk2) (reverse path)))) ==> (connect talk1 disconnect connect talk2 disconnect) |