source: project/wiki/tagged-begin @ 8860

Last change on this file since 8860 was 8860, checked in by Alaric Snell-Pym, 12 years ago

Found out how to write Jens Axel Søgaard in wiki markup :-)

File size: 7.6 KB
Line 
1[[tags: egg]]
2
3== Introduction
4
5A form of {{begin}} that resembles the Common Lisp {{tagbody}} construct.
6
7== Examples
8
9Example 1 ({{tagged-begin}} returns {{(void)}})
10
11<example>
12  <init>(use tagged-begin)</init>
13  <expr>(let ([i 0])
14   (tagged-begin
15    loop (set! i (+ i 1))
16         (if (< i 41) (go loop)))
17   i)</expr>
18   <result>41</result>
19</example>
20
21Example 2 ({{tagged-begin}} returns {{42}})
22
23<example>
24  <init>(use tagged-begin)</init>
25  <expr>(let ([i 0])
26   (tagged-begin
27    loop (set! i (+ i 1))
28         (if (< i 42) (go loop))
29         (return i)))</expr>
30  <result>42</result>
31</example>
32
33Example 3 ({{tagged-begin}} returns {{43}})
34
35<example>
36  <init>(use tagged-begin)</init>
37  <expr>(let ([i 0])
38   (tagged-begin
39    loop (set! i (+ i 1))
40         (go b)
41    a    (if (< i 43) (go loop))
42         (return i)
43    b    (go a)))</expr>
44  <result>43</result>
45</example>
46
47Example 4 ([[http://www.emacswiki.org/cgi-bin/wiki.pl?StateMachine]])
48
49<example>
50  <init>(use tagged-begin)</init>
51  <expr>(begin
52  (define (display/nl v)
53    (display v)
54    (newline))
55
56  (let ((a 0))
57   (tagged-begin
58     start
59      (set! a 0)
60     part-1
61      (set! a (+ a 1))
62      (display/nl a)
63      (cond
64        ((>= a  9)  (go end))
65        ((even? a)  (go part-1))
66        (else       (go part-2)))
67     part-2
68      (set! a (+ a 1))
69      (go part-1)
70     end
71      (display/nl "We're done printing the odd numbers between 0 and 10"))))</expr>
72  <output>1
733
745
757
769
77We're done printing the odd numbers between 0 and 10</output>
78</example>
79
80Example 5 ( Knuth: "The Art of Computer Programming", vol1, p.176): Inplace inversion of a permutation represented as a vector.
81
82<example>
83  <init>(use tagged-begin)</init>
84  <expr>(begin
85
86  (define permutation (vector 'dummy 6 2 1 5 4 3))      ; (Knuth counts from 1 not 0 :-) )
87  (define n           (- (vector-length permutation) 1))
88  (define (X i)       (vector-ref permutation i))
89  (define (X! i j)    (vector-set! permutation i j))
90
91  (let ([m 0] [i 0] [j 0])
92    (tagged-begin
93     I1   ; Initialize
94          (set! m n)
95          (set! j -1)
96     I2   ; Next element
97          (set! i (X m))
98          (if (< i 0) (go I5))
99     I3   ; Invert one
100          (X! m j)
101          (set! j (- m))
102          (set! m i)
103          (set! i (X m))
104     I4   ; End of cycle?
105          (if (> i 0) (go I3))
106          (set! i j)
107     I5   ; Store final value
108          (X! m (- i))
109     I6   ; Loop on m
110          (set! m (- m 1))
111          (if (> m 0) (go I2))))
112
113  permutation)</expr>
114  <result>#(dummy 3 2 6 5 4 1)</result>
115</example>
116
117Example 6 (The CommonLisp Hyper Spec examples of {{tagbody}})
118
119<example>
120  <init>(use tagged-begin)</init>
121  <expr>(begin
122  (define val 'foo)
123  (tagged-begin
124    (set! val 1)
125       (go a)
126   c   (set! val (+ val 4))
127       (go b)
128       (set! val (+ val 32))
129   a   (set! val (+ val 2))
130       (go c)
131       (set! val (+ val 64))
132   b   (set! val (+ val 8)))
133
134  (define (f1 flag)
135    (let ((n 1))
136      (tagged-begin
137       (set! n (f2 flag (lambda () (go out))))
138       out
139       (return n))))
140
141  (define (f2 flag escape)
142    (if flag (escape) 2))
143
144  (list val (f1 #f) (f1 #t)))</expr>
145  <result>(15 2 1)</result>
146</example>
147
148Example 7: Demonstrates lexical scoping of tagged-begins, and that an inner tagged-begin can use an outer tag.
149
150<example>
151  <init>(use tagged-begin)</init>
152  <expr>(tagged-begin
153 a (tagged-begin
154      (go b))
155 b (return 'hello-world))</expr>
156  <result>hello-world</result>
157</example>
158
159Example 8: Demonstrates that tags are lexically shadowed.
160
161<example>
162  <init>(use tagged-begin)</init>
163  <expr>(tagged-begin
164 a (tagged-begin
165        (go b)
166        (return 'wrong)
167      b (go c))
168 b (return 'wrong)
169 c (return 'correct))</expr>
170  <result>correct</result>
171</example>
172
173Expansion example:
174
175<example>
176  <init>(use tagged-begin)</init>
177  <expr>(pp (macroexpand
178  '(tagged-begin
179       (set! val 1)
180       (go a)
181 c     (set! val (+ val  4))
182       (go b)
183       (set! val (+ val 32))
184 a     (set! val (+ val  2))
185       (go c)
186       (set! val (+ val 64))
187 b     (set! val (+ val  8)))))</expr>
188 <output>((call/cc
189    (lambda (go)
190      (let ((return (lambda (v) (go (lambda () v)))))
191        (letrec ((g14 (lambda () (set! val 1) (go a) (c)))
192                 (c (lambda ()
193                      (set! val (+ val 4))
194                      (go b)
195                      (set! val (+ val 32))
196                      (a)))
197                 (a (lambda ()
198                      (set! val (+ val 2))
199                      (go c)
200                      (set! val (+ val 64))
201                      (b)))
202                 (b (lambda () (set! val (+ val 8)) (return (void)))))
203          (g14))))))</output>
204</example>
205
206== Authors
207
208Jens Axel <nowiki>S&oslash;gaard</nowiki>, low-level macro implementation by [[felix winkelmann|Felix Winkelmann]].
209
210== License
211
212Copyright (c) 2005, Jens Axel <nowiki>S&oslash;gaard</nowiki>
213All rights reserved.
214
215Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
216conditions are met:
217
218* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
219* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
220* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
221
222THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
223OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
224AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
225CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
226CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
227SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
228THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
229OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
230POSSIBILITY OF SUCH DAMAGE.
231
232== Documentation
233
234This is a little macro that resembles the Common Lisp [[http://www-2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/speope_tagbody.html#tagbody|tagbody]] construct.
235See also "Applications of Continuations" of Daniel P. Friedman.
236
237=== Motivation
238
239Many algorithms is specified in an imperative manner
240in the literature (see Example 5 from Knuth). For a no-brain-
241conversion to Scheme tagged-begin is convenient.
242
243=== Syntax
244 
245<macro> (tagged-begin (''tag'' | ''expression'')* )</macro>
246
247where {{tag}} is a symbol and duplicate tags are not allowed.
248
249=== Semantics
250
251The form evaluates the expressions in a lexical environment
252that provides functions {{go}} and {{return}} both of one argument to transfer control.
253
254The expressions in {{tagged-begin}} are evaluated sequentially.
255If no expressions are left {{(void)}} is returned.
256
257If an expression evaluates {{(go ''tag'')}} then control is transfered
258to the expression following tag. The tags have lexical scope.
259The dynamic extent of tag is indefinite.  An {{(go ''tag'')}} is allowed
260to transfer control to an outer tagbody. The call {{(go ''tag'')}} has the
261proper tail recursive property, even in a situation where the call
262syntactically is not in tail position.
263
264If {{(return ''expression'')}} is evaluted, the value of {{expression}} is
265the value of the entire tagged-begin form.
266
267== Version History
268
269* 1.1: {{tagged-begin.scm}} needed srfi-1
270* 1.0
Note: See TracBrowser for help on using the repository browser.