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

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

continuations 1.4.1 with current-continuation renamed escape-procedure

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==== escape-procedure
41
42<procedure>(escape-procedure)</procedure>
43
44captures and returns the current continuation as an escape procedure.
45Typically used as follows
46
47<enscript highlight=scheme>
48(let ((cc (escape-procedure)))
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</enscript>
57
58Note, that the let is invoked twice, first after the call to
59escape-procedure, then with the object val, which was
60bound to cc by calling (cc val).
61
62==== escape-procedure?
63
64<procedure>(escape-procedure? xpr)</procedure>
65
66type predicate, defined simultaneously with escape-procedure
67
68
69=== The continuation interface
70
71==== continuation
72
73<procedure>(continuation)</procedure>
74
75deprecated, use current instead.
76
77==== current
78
79<procedure>(current)</procedure>
80
81captures and returns the current continuation. Typically used as follows
82
83<enscript highlight=scheme>
84(let ((cc (current)))
85  (if (continuation? cc)
86    ... (throw cc val) ...
87    ... do something with val ...))
88</enscript>
89
90Note, that the let is invoked twice, first after the call to
91current, then with the object val, which was thrown to cc.
92
93==== continuation?
94
95<procedure>(continuation? xpr)</procedure>
96
97type predicate
98
99==== continuation->procedure
100
101<procedure>(continuation->procedure cont)</procedure>
102
103transforms a continuation into a procedure
104
105==== capture
106
107<procedure>(capture proc)</procedure>
108
109The same as call/cc but with a different datatype:
110Captures the current continuation as a continuation datatype (contrary
111to a procedure datatype in call/cc) and calls proc with that
112continuation as its only argument.
113
114==== graft
115
116<procedure>(graft cont thunk)</procedure>
117
118tail-calls thunk with the implicit continuation cont.
119
120==== throw
121
122<procedure>(throw cont val ....)</procedure>
123
124throws the values val .... to the continuation cont.
125
126==== catch
127
128<macro>(catch cont xpr ....)</macro>
129
130The same as let/cc of miscmacros but with a different datatype:
131Binds the cont variable to the current continuation as a continuation
132and executes the body xpr .... in this context. Typically used as
133follows
134 
135<enscript highlight=scheme>
136(catch k
137  ...
138  (if ...
139    (throw k val)
140    ...))
141</enscript>
142
143==== goto
144
145<procedure>(goto cc)</procedure>
146
147The infamous goto, but with a continuation as argument instead of a label.
148
149==== call
150
151<procedure>(call receiver)</procedure>
152
153The same as call/cc, but implemented via capture.
154
155==== continuations
156
157<procedure>(continuations sym ..)</procedure>
158
159documentation procedure
160
161=== The module continuations-used
162
163==== continuations-used
164
165<procedure>(continuations-used sym ..)</procedure>
166
167the usual documentation procedure
168
169==== make-amb
170
171<procedure>(make-amb)</procedure>
172
173produces an ambiguous choice object, which accepts three messages,
174'choose, 'fail and 'assert.
175
176==== make-threads
177
178<procedure>(make-threads)</procedure>
179
180produces a threads object, which accepts five messages,
181'halt, 'quit, 'spawn, 'yield and 'start, implementing cooperative
182threads.
183
184==== iterate
185
186<macro>(iterate var iterator xpr . xprs)</macro>
187
188iterates var over iterater and applies the body, xpr . xprs, to each
189item. iterator should be a curried procedure of a container and a yield
190routine, the latter supplying one value at each pass.
191
192=== Examples
193
194==== escape procedures
195
196<enscript highlight=scheme>
197(use continuations)
198
199(define (product . nums)
200  (let ((cc (current-continuation)))
201    (cond
202      ((escape-procedure? cc) ; continuation cc just created
203       (print "NORMAL BODY")
204       (cond
205         ((null? nums) 1)
206         ((zero? (car nums))
207          (cc 0))
208         (else
209           (* (car nums) (apply product (cdr nums))))))
210      ((number? cc) ; cc has been thrown a number
211       (print "EXCEPTIONAL CASE")
212       cc)
213      )))
214
215</enscript>
216
217==== amb
218
219<enscript highlight=scheme>
220(require-library continuations)
221(import continuations continuations-used)
222
223(define amb (make-amb))
224
225(define (pythagoras . choices)
226  (let ((a (apply (amb 'choose) choices))
227        (b (apply (amb 'choose) choices))
228        (c (apply (amb 'choose) choices)))
229    ((amb 'assert) (= (* c c) (+ (* a a) (* b b))))
230    ((amb 'assert) (< b a))
231    (list a b c)))
232
233(pythagoras 1 2 3 4 5 6 7) ; -> (4 3 5)
234</enscript>
235
236==== cooperative threads
237
238<enscript highlight=scheme>
239(require-library continuations)
240(import continuations continuations-used)
241
242(define threads (make-threads))
243
244(define make-thunk
245        (let ((counter 10))
246                (lambda (name)
247                        (rec (loop)
248                                (if (< counter 0)
249                                        ((threads 'quit)))
250                                (print (cons name counter))
251                                (set! counter (- counter 1))
252                                ((threads 'yield))
253                                (loop)))))
254
255((threads 'spawn) (make-thunk 'a))
256((threads 'spawn) (make-thunk 'aa))
257((threads 'spawn) (make-thunk 'aaa))
258((threads 'start))
259
260; prints (a . 10) (aa . 9) (aaa . 8) (a . 7) (aa . 6) (aaa . 5)
261;        (a . 4) (aa .  3) (aaa . 2) (a . 1) (aa . 0)
262; in sequence
263</enscript>
264
265==== iterators
266
267<enscript highlight=scheme>
268(require-library continuations)
269(import continuations continuations-used)
270
271;; define an iterator for tree, i.e. a function of yield, which returns
272;; one tree-item at each pass
273(define (tree-iterator tree)
274  (lambda (yield)
275    (let walk ((tree tree))
276      (if (pair? tree)
277        (begin (walk (car tree))
278               (walk (cdr tree)))
279        (yield tree)))))
280
281(iterate var (tree-iterator '(3 . ((4 . 5) . 6))) (print var))
282; prints 3 4 5 6 in sequence
283</enscript>
284
285== Requirements
286
287none
288
289== Last update
290
291Nov 09, 2016
292
293== Author
294
295[[/users/juergen-lorenz|Juergen Lorenz]]
296
297== License
298
299 Copyright (c) 2013-2016, Juergen Lorenz
300 All rights reserved.
301
302 Redistribution and use in source and binary forms, with or without
303 modification, are permitted provided that the following conditions are
304 met:
305 
306 Redistributions of source code must retain the above copyright
307 notice, this list of conditions and the following disclaimer.
308 
309 Redistributions in binary form must reproduce the above copyright
310 notice, this list of conditions and the following disclaimer in the
311 documentation and/or other materials provided with the distribution.
312 Neither the name of the author nor the names of its contributors may be
313 used to endorse or promote products derived from this software without
314 specific prior written permission.
315   
316 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
317 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
318 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
319 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
320 HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
321 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
322 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
323 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
324 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
325 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
326 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
327
328== Version History
329
330; 1.4.1 : current-continuation renamed escape-procedure
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.