control-features.texinfo (15431B)
1 @node Control features 2 @section Control features 3 4 This section describes various primitive procedures which control 5 the flow of program execution in special ways. Procedures in this 6 section that invoke procedure arguments always do so in the same 7 dynamic environment as the call of the original procedure. The 8 @code{procedure?} predicate is also described here. 9 10 @deffn procedure procedure? obj 11 12 Returns @code{#t} if 13 @var{obj} is a procedure, otherwise returns @code{#f}. 14 15 @lisp 16 (procedure? car) @result{} #t 17 (procedure? 'car) @result{} #f 18 (procedure? (lambda (x) (* x x))) 19 @result{} #t 20 (procedure? '(lambda (x) (* x x))) 21 @result{} #f 22 (call-with-current-continuation procedure?) 23 @result{} #t 24 @end lisp 25 26 @end deffn 27 28 @deffn procedure apply proc @vari{arg}@dots{} args 29 30 The @code{apply} procedure calls @var{proc} with the elements of the 31 list @code{(append (list }@vari{arg} @dots{}@code{) args)} as the 32 actual arguments. 33 34 @lisp 35 (apply + (list 3 4)) @result{} 7 36 37 (define compose 38 (lambda (f g) 39 (lambda args 40 (f (apply g args))))) 41 42 ((compose sqrt *) 12 75) @result{} 30 43 @end lisp 44 45 @end deffn 46 47 @deffn procedure map proc @vari{list} @varii{list}@dots{} 48 49 It is an error if @var{proc} does not accept as many arguments as 50 there are @var{list}s and return a single value. 51 52 The @code{map} procedure applies @var{proc} element-wise to the 53 elements of the @var{list}s and returns a list of the results, in 54 order. If more than one @var{list} is given and not all lists have 55 the same length, @code{map} terminates when the shortest list runs out. 56 The @var{list}s can be circular, but it is an error if all of them are 57 circular. It is an error for @var{proc} to mutate any of the lists. 58 The dynamic order in which @var{proc} is applied to the elements 59 of the @var{list}s is unspecified. If multiple returns occur from 60 @code{map}, the values returned by earlier returns are not mutated. 61 62 @lisp 63 (map cadr '((a b) (d e) (g h))) @result{} (b e h) 64 65 (map (lambda (n) (expt n n)) 66 '(1 2 3 4 5)) 67 @result{} (1 4 27 256 3125) 68 69 (map + '(1 2 3) '(4 5 6 7)) @result{} (5 7 9) 70 71 (let ((count 0)) 72 (map (lambda (ignored) 73 (set! count (+ count 1)) 74 count) 75 '(a b))) 76 @result{} (1 2) @r{or} (2 1) 77 @end lisp 78 79 @end deffn 80 81 @deffn procedure string-map proc @vari{string} @varii{string}@dots{} 82 83 It is an error if @var{proc} does not accept as many arguments as 84 there are @var{string}s and return a single character. 85 86 The @code{string-map} procedure applies @var{proc} element-wise to 87 the elements of the @var{string}s and returns a string of the results, 88 in order. If more than one @var{string} is given and not all strings 89 have the same length, @code{string-map} terminates when the shortest 90 string runs out. The dynamic order in which @var{proc} is applied 91 to the elements of the @var{string}s is unspecified. If multiple 92 returns occur from @code{string-map}, the values returned by earlier 93 returns are not mutated. 94 95 @lisp 96 (string-map char-foldcase "AbdEgH") @result{} "abdegh" 97 98 (string-map 99 (lambda (c) 100 (integer->char (+ 1 (char->integer c)))) 101 "HAL") 102 @result{} "IBM" 103 104 (string-map 105 (lambda (c k) 106 ((if (eqv? k #\u) char-upcase char-downcase) 107 c)) 108 "studlycaps xxx" 109 "ululululul") 110 @result{} "StUdLyCaPs" 111 @end lisp 112 113 @end deffn 114 115 @deffn procedure vector-map proc @vari{vector} @varii{vector}@dots{} 116 117 It is an error if @var{proc} does not accept as many arguments as 118 there are @var{vector}s and return a single value. 119 120 The @code{vector-map} procedure applies @var{proc} element-wise to 121 the elements of the @var{vector}s and returns a vector of the results, 122 in order. If more than one @var{vector} is given and not all vectors 123 have the same length, @code{vector-map} terminates when the shortest 124 vector runs out. The dynamic order in which @var{proc} is applied 125 to the elements of the @var{vector}s is unspecified. If multiple 126 returns occur from @code{vector-map}, the values returned by earlier 127 returns are not mutated. 128 129 @lisp 130 (vector-map cadr '#((a b) (d e) (g h))) @result{} #(b e h) 131 132 (vector-map (lambda (n) (expt n n)) 133 '#(1 2 3 4 5)) 134 @result{} #(1 4 27 256 3125) 135 136 (vector-map + '#(1 2 3) '#(4 5 6 7)) @result{} #(5 7 9) 137 138 (let ((count 0)) 139 (vector-map 140 (lambda (ignored) 141 (set! count (+ count 1)) 142 count) 143 '#(a b))) 144 @result{} #(1 2) @r{or} #(2 1) 145 @end lisp 146 147 @end deffn 148 149 @deffn procedure for-each proc @vari{list} @varii{list}@dots{} 150 151 It is an error if @var{proc} does not accept as many arguments as 152 there are @var{list}s. 153 154 The arguments to @code{for-each} are like the arguments to @code{map}, 155 but @code{for-each} calls @var{proc} for its side effects rather than 156 for its values. Unlike @code{map}, @code{for-each} is guaranteed 157 to call @var{proc} on the elements of the @var{list}s in order 158 from the first element(s) to the last, and the value returned by 159 @code{for-each} is unspecified. If more than one @var{list} is given 160 and not all lists have the same length, @code{for-each} terminates 161 when the shortest list runs out. The @var{list}s can be circular, 162 but it is an error if all of them are circular. 163 164 It is an error for @var{proc} to mutate any of the lists. 165 166 @lisp 167 (let ((v (make-vector 5))) 168 (for-each (lambda (i) 169 (vector-set! v i (* i i))) 170 '(0 1 2 3 4)) 171 v) 172 @result{} #(0 1 4 9 16) 173 @end lisp 174 @end deffn 175 176 @deffn procedure string-for-each proc string1 string2@dots{} 177 178 It is an error if @var{proc} does not accept as many arguments as 179 there are @var{string}s. 180 181 The arguments to @code{string-for-each} are like the arguments to 182 @code{string-map}, but @code{string-for-each} calls @var{proc} for its 183 side effects rather than for its values. Unlike @code{string-map}, 184 @code{string-for-each} is guaranteed to call @var{proc} on the elements 185 of the @var{string}s in order from the first element(s) to the last, 186 and the value returned by @code{string-for-each} is unspecified. 187 If more than one @var{string} is given and not all strings have the 188 same length, @code{string-for-each} terminates when the shortest string 189 runs out. It is an error for @var{proc} to mutate any of the strings. 190 191 @lisp 192 (let ((v '())) 193 (string-for-each 194 (lambda (c) (set! v (cons (char->integer c) v))) 195 "abcde") 196 v) 197 @result{} (101 100 99 98 97) 198 @end lisp 199 200 @end deffn 201 202 @deffn procedure vector-for-each proc @vari{vector} @varii{vector}@dots{} 203 204 It is an error if @var{proc} does not accept as many arguments as 205 there are @var{vector}s. 206 207 The arguments to @code{vector-for-each} are like the arguments to 208 @code{vector-map}, but @code{vector-for-each} calls @var{proc} for its 209 side effects rather than for its values. Unlike @code{vector-map}, 210 @code{vector-for-each} is guaranteed to call @var{proc} on the elements 211 of the @var{vector}s in order from the first element(s) to the last, 212 and the value returned by @code{vector-for-each} is unspecified. 213 If more than one @var{vector} is given and not all vectors have the 214 same length, @code{vector-for-each} terminates when the shortest vector 215 runs out. It is an error for @var{proc} to mutate any of the vectors. 216 217 @lisp 218 (let ((v (make-list 5))) 219 (vector-for-each 220 (lambda (i) (list-set! v i (* i i))) 221 '#(0 1 2 3 4)) 222 v) 223 @result{} (0 1 4 9 16) 224 @end lisp 225 226 @end deffn 227 228 @deffn procedure call-with-current-continuation proc 229 @deffnx procedure call/cc proc 230 231 It is an error if @var{proc} does not accept one 232 argument. 233 234 @cindex escape procedure 235 236 The procedure @code{call-with-current-continuation} (or its equivalent 237 abbreviation @code{call/cc}) packages the current continuation (see 238 the rationale below) as an ``escape procedure'' and passes it as an 239 argument to @var{proc}. The escape procedure is a Scheme procedure 240 that, if it is later called, will abandon whatever continuation is in 241 effect at that later time and will instead use the continuation that 242 was in effect when the escape procedure was created. Calling the 243 escape procedure will cause the invocation of @var{before} and 244 @var{after} thunks installed using @code{dynamic-wind}. 245 246 The escape procedure accepts the same number of 247 arguments as the continuation to the original call to 248 @code{call-with-current-continuation}. Most continuations take only 249 one value. Continuations created by the @code{call-with-values} 250 procedure (including the initialization expressions of 251 @code{define-values}, @code{let-values}, and @code{let*-values} 252 expressions), take the number of values that the consumer expects. 253 The continuations of all non-final expressions within a sequence 254 of expressions, such as in @code{lambda}, @code{case-lambda}, 255 @code{begin}, @code{let}, @code{let*}, @code{letrec}, @code{letrec*}, 256 @code{let-values}, @code{let*-values}, @code{let-syntax}, 257 @code{letrec-syntax}, @code{parameterize}, @code{guard}, @code{case}, 258 @code{cond}, @code{when}, and @code{unless} expressions, take an 259 arbitrary number of values because they discard the values passed to 260 them in any event. The effect of passing no values or more than one 261 value to continuations that were not created in one of these ways 262 is unspecified. 263 264 The escape procedure that is passed to @var{proc} has unlimited 265 extent just like any other procedure in Scheme. It can be stored 266 in variables or data structures and can be called as many times as 267 desired. However, like the @code{raise} and @code{error} procedures, 268 it never returns to its caller. 269 270 The following examples show only the simplest ways in which 271 @code{call-with-current-continuation} is used. If all real uses were 272 as simple as these examples, there would be no need for a procedure 273 with the power of @code{call-with-current-continuation}. 274 275 @lisp 276 (call-with-current-continuation 277 (lambda (exit) 278 (for-each (lambda (x) 279 (if (negative? x) 280 (exit x))) 281 '(54 0 37 -3 245 19)) 282 #t)) 283 @result{} -3 284 285 (define list-length 286 (lambda (obj) 287 (call-with-current-continuation 288 (lambda (return) 289 (letrec ((r 290 (lambda (obj) 291 (cond ((null? obj) 0) 292 ((pair? obj) 293 (+ (r (cdr obj)) 1)) 294 (else (return #f)))))) 295 (r obj)))))) 296 297 (list-length '(1 2 3 4)) @result{} 4 298 299 (list-length '(a b . c)) @result{} #f 300 @end lisp 301 302 @rationale{} 303 304 A common use of @code{call-with-current-continuation} is for 305 structured, non-local exits from loops or procedure bodies, but in 306 fact @code{call-with-current-continuation} is useful for implementing a 307 wide variety of advanced control structures. In fact, @code{raise} and 308 @code{guard} provide a more structured mechanism for non-local exits. 309 310 Whenever a Scheme expression is evaluated there is a @define{continuation} 311 wanting the result of the expression. The continuation represents 312 an entire (default) future for the computation. If the expression is 313 evaluated at the REPL, for example, then the continuation might take 314 the result, print it on the screen, prompt for the next input, evaluate 315 it, and so on forever. Most of the time the continuation includes 316 actions specified by user code, as in a continuation that will take 317 the result, multiply it by the value stored in a local variable, add 318 seven, and give the answer to the REPL's continuation to be printed. 319 Normally these ubiquitous continuations are hidden behind the scenes 320 and programmers do not think much about them. On rare occasions, 321 however, a programmer needs to deal with continuations explicitly. 322 The @code{call-with-current-continuation} procedure allows Scheme 323 programmers to do that by creating a procedure that acts just like 324 the current continuation. 325 326 @end deffn 327 328 @deffn procedure values obj@dots{} 329 330 Delivers all of its arguments to its continuation. The @code{values} 331 procedure might be defined as follows: 332 333 @lisp 334 (define (values . things) 335 (call-with-current-continuation 336 (lambda (cont) (apply cont things)))) 337 @end lisp 338 339 @end deffn 340 341 @deffn procedure call-with-values producer consumer 342 343 Calls its @var{producer} argument with no arguments and a continuation 344 that, when passed some values, calls the @var{consumer} procedure with 345 those values as arguments. The continuation for the call to 346 @var{consumer} is the continuation of the call to 347 @code{call-with-values}. 348 349 @lisp 350 (call-with-values (lambda () (values 4 5)) 351 (lambda (a b) b)) 352 @result{} 5 353 354 (call-with-values * -) @result{} -1 355 @end lisp 356 @end deffn 357 358 @deffn procedure dynamic-wind before thunk after 359 360 Calls @var{thunk} without arguments, returning the result(s) of this 361 call. @var{Before} and @var{after} are called, also without arguments, 362 as required by the following rules. Note that, in the absence of calls 363 to continuations captured using @code{call-with-current-continuation}, 364 the three arguments are called once each, in order. @var{Before} 365 is called whenever execution enters the dynamic extent of the 366 call to @var{thunk} and @var{after} is called whenever it exits 367 that dynamic extent. The dynamic extent of a procedure call is 368 the period between when the call is initiated and when it returns. 369 The @var{before} and @var{after} thunks are called in the same dynamic 370 environment as the call to @code{dynamic-wind}. In Scheme, because of 371 @code{call-with-current-continuation}, the dynamic extent of a call is 372 not always a single, connected time period. It is defined as follows: 373 374 @itemize @bullet 375 376 @item 377 The dynamic extent is entered when execution of the body of the 378 called procedure begins. 379 380 @item 381 The dynamic extent is also entered when execution is not within 382 the dynamic extent and a continuation is invoked that was captured 383 (using @code{call-with-current-continuation}) during the dynamic 384 extent. 385 386 @item 387 It is exited when the called procedure returns. 388 389 @item 390 It is also exited when execution is within the dynamic extent and a 391 continuation is invoked that was captured while not within the dynamic 392 extent. 393 394 @end itemize 395 396 If a second call to @code{dynamic-wind} occurs within the dynamic 397 extent of the call to @var{thunk} and then a continuation is invoked 398 in such a way that the @var{after}s from these two invocations of 399 @code{dynamic-wind} are both to be called, then the @var{after} 400 associated with the second (inner) call to @code{dynamic-wind} is 401 called first. 402 403 If a second call to @code{dynamic-wind} occurs within the dynamic 404 extent of the call to @var{thunk} and then a continuation is invoked 405 in such a way that the @var{before}s from these two invocations of 406 @code{dynamic-wind} are both to be called, then the @var{before} 407 associated with the first (outer) call to @code{dynamic-wind} is 408 called first. 409 410 If invoking a continuation requires calling the @var{before} from 411 one call to @code{dynamic-wind} and the @var{after} from another, 412 then the @var{after} is called first. 413 414 The effect of using a captured continuation to enter or exit the 415 dynamic extent of a call to @var{before} or @var{after} is unspecified. 416 417 @lisp 418 (let ((path '()) 419 (c #f)) 420 (let ((add (lambda (s) 421 (set! path (cons s path))))) 422 (dynamic-wind 423 (lambda () (add 'connect)) 424 (lambda () 425 (add (call-with-current-continuation 426 (lambda (c0) 427 (set! c c0) 428 'talk1)))) 429 (lambda () (add 'disconnect))) 430 (if (< (length path) 4) 431 (c 'talk2) 432 (reverse path)))) 433 434 @result{} (connect talk1 disconnect 435 connect talk2 disconnect) 436 @end lisp 437 438 @end deffn