source: project/wiki/eggref/4/continuations @ 33714

Last change on this file since 33714 was 33714, checked in by juergen, 3 years ago

parentheses fixed

File size: 9.1 KB
Line 
1[[tags: egg]]
2[[toc:]]
3
4== continuations
5
6This library contains two modules, continuations and continuations-used.
7
8The former provides some syntactic sugar to Marc Feeley's continuation
9interface. In this interface, continuations are a datatype separate from
10procedures. Hence it provides a continuation? predicate. I've stripped
11the prefix from the procedures continuation-capture and
12continuation-graft and renamed continuation-return throw. This latter
13procedure is accompanied in this module by a macro named catch, so that
14the usual catch-throw-semantics of other languages is available.  But
15note, that in this pattern, the continuation is a Scheme object, and
16like every Scheme object it has indefinite extent, hence can be
17exported, saved in other data-structures etc. So this pattern is much
18more powerful than the corresponding pattern in other languages.
19
20Some other procedures are provided as well, in particular
21continuation->procedure, which does what the name says, and
22continuations, which provides offline documentation to the module. Like
23in my other modules, the call (continuations) lists the exported
24symbols, and (continuations sym) provides documentation of the exported
25symbol sym.
26
27Moreover, another interface to continuations is provided, recommended by
28Matt Might, and that in two flavors, with continuations, checked by
29continuation?, and escape procedures, checked by escape-procedure?.
30This makes possible code written in an idiom similar to the
31setjmp-longjmp-pair in C.
32And then there is the infamous goto, which albeit dangerous is
33sometimes useful, e.g. in backtracking ....
34 
35The second module, continuations-used, provides some applications of the
36continuations module.
37
38=== The escape-procedure interface
39
40==== current-continuation
41
42<procedure>(current-continuation)</procedure>
43
44captures and returns the current continuation as an escape procedure.
45Typically used as follows
46
47<enscript highlight=scheme>
48(let ((cc (current-continuation)))
49  (cond
50    ((escape-procedure? cc)
51     ;; normal body
52     ;; possibly calling (cc val) ...
53    ((ok? cc)
54     ;; exceptional case
55     ;; do something with cc ...
56    ))
57</enscript>
58
59Note, that the let is invoked twice, first after the call to
60current-continuation, then with the object val, which was
61bound to cc by calling (cc val).
62
63==== escape-procedure?
64
65<procedure>(escape-procedure? xpr)</procedure>
66
67type predicate, defined simultaneously with current-continuation
68
69
70=== The continuation interface
71
72==== continuation
73
74<procedure>(continuation)</procedure>
75
76deprecated, use current instead.
77
78==== current
79
80<procedure>(current)</procedure>
81
82captures and returns the current continuation. Typically used as follows
83
84<enscript highlight=scheme>
85(let ((cc (current)))
86  (if (continuation? cc)
87    ... (throw cc val) ...
88    ... do something with val ...))
89</enscript>
90
91Note, that the let is invoked twice, first after the call to
92current, then with the object val, which was thrown to cc.
93
94==== continuation?
95
96<procedure>(continuation? xpr)</procedure>
97
98type predicate
99
100==== continuation->procedure
101
102<procedure>(continuation->procedure cont)</procedure>
103
104transforms a continuation into a procedure
105
106==== capture
107
108<procedure>(capture proc)</procedure>
109
110The same as call/cc but with a different datatype:
111Captures the current continuation as a continuation datatype (contrary
112to a procedure datatype in call/cc) and calls proc with that
113continuation as its only argument.
114
115==== graft
116
117<procedure>(graft cont thunk)</procedure>
118
119tail-calls thunk with the implicit continuation cont.
120
121==== throw
122
123<procedure>(throw cont val ....)</procedure>
124
125throws the values val .... to the continuation cont.
126
127==== catch
128
129<macro>(catch cont xpr ....)</macro>
130
131The same as let/cc of miscmacros but with a different datatype:
132Binds the cont variable to the current continuation as a continuation
133and executes the body xpr .... in this context. Typically used as
134follows
135 
136<enscript highlight=scheme>
137(catch k
138  ...
139  (if ...
140    (throw k val)
141    ...))
142</enscript>
143
144==== goto
145
146<procedure>(goto cc)</procedure>
147
148The infamous goto, but with a continuation as argument instead of a label.
149
150==== call
151
152<procedure>(call receiver)</procedure>
153
154The same as call/cc, but implemented via capture.
155
156==== continuations
157
158<procedure>(continuations sym ..)</procedure>
159
160documentation procedure
161
162=== The module continuations-used
163
164==== continuations-used
165
166<procedure>(continuations-used sym ..)</procedure>
167
168the usual documentation procedure
169
170==== make-amb
171
172<procedure>(make-amb)</procedure>
173
174produces an ambiguous choice object, which accepts three messages,
175'choose, 'fail and 'assert.
176
177==== make-threads
178
179<procedure>(make-threads)</procedure>
180
181produces a threads object, which accepts five messages,
182'halt, 'quit, 'spawn, 'yield and 'start, implementing cooperative
183threads.
184
185==== iterate
186
187<macro>(iterate var iterator xpr . xprs)</macro>
188
189iterates var over iterater and applies the body, xpr . xprs, to each
190item. iterator should be a curried procedure of a container and a yield
191routine, the latter supplying one value at each pass.
192
193=== Examples
194
195==== escape procedures
196
197<enscript highlight=scheme>
198(use continuations)
199
200(define (product . nums)
201  (let ((cc (current-continuation)))
202    (cond
203      ((escape-procedure? cc) ; continuation cc just created
204       (print "NORMAL BODY")
205       (cond
206         ((null? nums) 1)
207         ((zero? (car nums))
208          (cc 0))
209         (else
210           (* (car nums) (apply product (cdr nums))))))
211      ((number? cc) ; cc has been thrown a number
212       (print "EXCEPTIONAL CASE")
213       cc)
214      )))
215
216</enscript>
217
218==== amb
219
220<enscript highlight=scheme>
221(require-library continuations)
222(import continuations continuations-used)
223
224(define amb (make-amb))
225
226(define (pythagoras . choices)
227  (let ((a (apply (amb 'choose) choices))
228        (b (apply (amb 'choose) choices))
229        (c (apply (amb 'choose) choices)))
230    ((amb 'assert) (= (* c c) (+ (* a a) (* b b))))
231    ((amb 'assert) (< b a))
232    (list a b c)))
233
234(pythagoras 1 2 3 4 5 6 7) ; -> (4 3 5)
235</enscript>
236
237==== cooperative threads
238
239<enscript highlight=scheme>
240(require-library continuations)
241(import continuations continuations-used)
242
243(define threads (make-threads))
244
245(define make-thunk
246        (let ((counter 10))
247                (lambda (name)
248                        (rec (loop)
249                                (if (< counter 0)
250                                        ((threads 'quit)))
251                                (print (cons name counter))
252                                (set! counter (- counter 1))
253                                ((threads 'yield))
254                                (loop)))))
255
256((threads 'spawn) (make-thunk 'a))
257((threads 'spawn) (make-thunk 'aa))
258((threads 'spawn) (make-thunk 'aaa))
259((threads 'start))
260
261; prints (a . 10) (aa . 9) (aaa . 8) (a . 7) (aa . 6) (aaa . 5)
262;        (a . 4) (aa .  3) (aaa . 2) (a . 1) (aa . 0)
263; in sequence
264</enscript>
265
266==== iterators
267
268<enscript highlight=scheme>
269(require-library continuations)
270(import continuations continuations-used)
271
272;; define an iterator for tree, i.e. a function of yield, which returns
273;; one tree-item at each pass
274(define (tree-iterator tree)
275  (lambda (yield)
276    (let walk ((tree tree))
277      (if (pair? tree)
278        (begin (walk (car tree))
279               (walk (cdr tree)))
280        (yield tree)))))
281
282(iterate var (tree-iterator '(3 . ((4 . 5) . 6))) (print var))
283; prints 3 4 5 6 in sequence
284</enscript>
285
286== Requirements
287
288none
289
290== Last update
291
292Oct 16, 2016
293
294== Author
295
296[[/users/juergen-lorenz|Juergen Lorenz]]
297
298== License
299
300 Copyright (c) 2013-2016, Juergen Lorenz
301 All rights reserved.
302
303 Redistribution and use in source and binary forms, with or without
304 modification, are permitted provided that the following conditions are
305 met:
306 
307 Redistributions of source code must retain the above copyright
308 notice, this list of conditions and the following disclaimer.
309 
310 Redistributions in binary form must reproduce the above copyright
311 notice, this list of conditions and the following disclaimer in the
312 documentation and/or other materials provided with the distribution.
313 Neither the name of the author nor the names of its contributors may be
314 used to endorse or promote products derived from this software without
315 specific prior written permission.
316   
317 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
318 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
319 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
320 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321 HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
322 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
323 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
324 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
325 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
326 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
327 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
328
329== Version History
330
331; 1.4 : escape procedure interface added
332; 1.3 : continuation renamed current, call added
333; 1.2.4 : tests updated
334; 1.2.2 : tests updated
335; 1.2.1 : bug in setup file corrected
336; 1.2 : some tests rewritten and repackeged as an extra module continuations-used
337; 1.1.2 : test cases for iterators and cooperative threads added
338; 1.1.1 : bug fix in documentation procedure
339; 1.1 : added continuation and goto with the amb example
340; 1.0 : initial import
Note: See TracBrowser for help on using the repository browser.