|
| 1 | +# Control Flow |
| 2 | + |
| 3 | +## make-promise |
| 4 | +``` |
| 5 | +(make-promise thunk) -> promise |
| 6 | +
|
| 7 | + thunk := procedure taking no args |
| 8 | +``` |
| 9 | + |
| 10 | +Creates a promise. You can access the result of the promise with `force`, |
| 11 | +which will compute the `thunk` the first time, memoize its result, and subsequently return it always. |
| 12 | + |
| 13 | +Note: The syntax `(delay expr)` creates a promise as if by `(make-promise (lambda () expr))` |
| 14 | + |
| 15 | +Beware: promises returned by `make-promise` are optimized for efficient use in a single-threaded context, |
| 16 | +and are not thread-safe, nor safe against escaping continuations that somehow reenter the thunk |
| 17 | +before it was fully computed. If you want safety in those cases, use `make-atomic-promise` below. |
| 18 | + |
| 19 | +## promise? |
| 20 | +``` scheme |
| 21 | +(promise? obj) -> boolean |
| 22 | +
|
| 23 | + obj := any object |
| 24 | +``` |
| 25 | + |
| 26 | +Returns true if the object *obj* is a promise. |
| 27 | + |
| 28 | +## make-atomic-promise |
| 29 | +``` |
| 30 | +(make-atomic-promise thunk) -> promise |
| 31 | +
|
| 32 | + thunk := procedure taking no args |
| 33 | +``` |
| 34 | + |
| 35 | +Creates a promise that is safe in a single-threaded context. |
| 36 | +The promise can be fulfilled with the usual `force` primitive, same as with `make-promise`. |
| 37 | + |
| 38 | +It is safe for users in multiple threads to simultaneously try to force the promise: |
| 39 | +the first user will do the work, the other ones will wait for its result. |
| 40 | +The thunk of an atomic-promise will have only one instance running at once, |
| 41 | +and may complete only once, after which it will run no more and the result will be reused instead. |
| 42 | +In case of errors and retries from a caller, |
| 43 | +the partial side-effects of the incomplete thunk may happen |
| 44 | +more than once, so the thunk is responsible for appropriately protecting |
| 45 | +any data structure that may be affected, or for ensuring its partial effects are idempotent. |
| 46 | + |
| 47 | +If an error occurs while computing the thunk, or evaluation otherwise escapes from the thunk, |
| 48 | +the calling thread may catch the error or escaping value and process it; |
| 49 | +but it is an error that will be caught to then try to resume evaluation of the thunk |
| 50 | +from a continuation captured within it. |
| 51 | +Instead, the promise may be forced again by the same thread or another concurrent thread, |
| 52 | +that will hopefully evaluate the thunk to completion and return its result, |
| 53 | +or then again may in turn error out and escape. |
| 54 | + |
| 55 | + |
| 56 | +## call-with-parameters |
| 57 | +``` scheme |
| 58 | +(call-with-parameters thunk . parameterization) -> any |
| 59 | +
|
| 60 | + thunk := procedure taking no args |
| 61 | +
|
| 62 | +parameterization: |
| 63 | + parameter value ... |
| 64 | +``` |
| 65 | + |
| 66 | +Calls *thunk* with parameterization. |
| 67 | + |
| 68 | +## with-catch |
| 69 | +``` scheme |
| 70 | +(with-catch handler thunk) -> any |
| 71 | +
|
| 72 | + handler, thunk := procedure |
| 73 | +``` |
| 74 | + |
| 75 | +Calls *thunk* with *handler* as the exception catcher. |
| 76 | + |
| 77 | +## with-unwind-protect |
| 78 | +``` scheme |
| 79 | +(with-unwind-protect thunk fini) -> any |
| 80 | +
|
| 81 | + thunk, fini := procedure |
| 82 | +``` |
| 83 | + |
| 84 | +Calls *thunk*, invoking *fini* when execution exits the dynamic extent |
| 85 | +of *thunk*. |
| 86 | + |
0 commit comments