source: project/wiki/eggref/4/cooperative @ 34704

Last change on this file since 34704 was 34704, checked in by wasamasa, 3 years ago

Fix typo

File size: 5.7 KB
Line 
1[[toc:]]
2== cooperative
3
4Coroutines and Finite State Machines for Chicken Scheme
5
6=== Installing
7<enscript> 
8chicken-install cooperative
9</enscript>
10
11=== Usage
12<enscript highlight="scheme">
13(use cooperative)
14</enscript>
15
16==== make-coroutine
17<procedure>(make-coroutine proc . args)</procedure>
18
19Returns a new coroutine. The resulting procedure is a thunk
20(it takes no arguments). When the coroutine is called, it is equivalent to applying
21''args'' to ''proc'', except that any calls to ''yield!''
22will return control to the calling procedure. When the coroutine is called again
23after ''yield!'', it will continue where it left off before yielding
24An error is signalled if the coroutine is called after it completes
25without calling ''yield!''.
26
27===== Example
28<enscript highlight="scheme">
29(define (from-x-to-y x y)
30  (let loop ()
31    (if (< x y)
32      (begin (yield! x)
33             (set! x (add1 x))
34             (loop))
35      y)))
36
37(define from-1-to-3 (make-coroutine from-x-to-y 1 3))
38
39(from-1-to-3)
401
41(from-1-to-3)
422
43(from-1-to-3)
443
45(from-1-to-3)
46error "coroutine has finished"
47</enscript>
48
49==== in-coroutine?
50<procedure>(in-coroutine?)</procedure>
51
52Returns true if it is called within a coroutine created with a call
53to ''make-coroutine''. Else returns false.
54
55===== Example
56<enscript highlight="scheme">
57(define (maybe-coroutine)
58  (let loop ((x 0))
59    (if (in-coroutine?)
60      (yield! 'yielded))
61    (if (= x 3)
62      x
63      (loop (add1 x)))))
64 
65  (maybe-coroutine)
66  3
67 
68  (define coroutine (make-coroutine maybe-coroutine))
69  (coroutine)
70  yielded
71  (coroutine)
72  yielded
73  (coroutine)
74  yielded
75  (coroutine)
76  yielded
77  (coroutine)
78  3
79</enscript>
80==== yield!
81
82<procedure>(yield! [val])</procedure>
83
84Exits the current coroutine returning control to the calling
85procedure. Returns the optional value ''val'', which defaults to (void). An error
86is singled if ''yield!'' is called outside of a coroutine procedure.
87
88===== Example
89See ''make-coroutine''
90
91==== fsm
92<macro>(fsm input: (input ...) vars: vars start: initial-state state ...)</macro>
93
94Creates a finite state machine. The resulting machine is a procedure which
95behaves differently with subsequent calls depending on what state it is in.
96
97The machine parameters consist of literals followed by a relevant expression.
98these parameters must be outlined in the order they are shown above.
99
100'''input: (input ...)''' A list of input values. These are received as arguments
101to the finite state machine when it is called, and can be referenced as
102variables within the state machine.
103
104'''vars: vars''' A list of variable assignments equivalent to those found
105in a ''let'' expression. These variables are internal to the state machine and
106persist between calls to it, unless specifically changed.
107
108'''start: initial-state''' The name of the initial state. This is the state in
109which the finite state machine will be in when it is first called. The name of
110the initial state is not evaluated, and does not need to be quoted.
111
112The remaining parameters are state definitions, which also consist of literals
113followed by relevant expressions. Like the above parameters, they must be
114written in the order shown:
115
116'''(state: state-name act: act output: (output ...) trans: ((condition next-state) ...))'''
117
118'''state: state-name''' The state name. This is the name of the state being
119defined and is used to refer to this state during transitions. This name is not
120evaluated, and does not need to be quoted.
121
122'''act: act''' The state's action expression. This consists
123of a single scheme expression. Forms such as ''let'' or ''begin'' should be used
124to perform multiple actions here.
125
126'''output: (output ...)''' Followed by a list of output values. A list containing all values
127specified here will be returned to the calling procedure. The list should not
128be quoted, quasiquoted or created with the list procedure, simply specified
129with parentheses, although individual elements will be evaluated.
130
131'''trans: ((condition next-state) ...)''' The state transitions list. This is an association list
132containing boolean expressions paired with states to transition to. The next time the
133finite state machine is called, it will be in the state paired with the
134first predicate to return true. The state names are not evaluated and do not
135need to be quoted.
136
137#### Example
138<enscript highlight="scheme">
139(define docking-control
140  (fsm
141    input: (use-case)
142    vars: ((ports 3) (ships 0) (status #f))
143    start: empty
144
145    (state: empty
146      act: (case use-case
147             ((arrival) (begin (set! ships (add1 ships))
148                               (set! status 'approved)))
149             ((departure) (set! status 'denied))
150             (else (error "invalid use case")))
151      output: (status)
152      trans: (((< 0 ships) else)))
153
154    (state: full
155      act: (case use-case
156             ((arrival) (set! status 'denied))
157             ((departure) (begin (set! ships (sub1 ships))
158                                 (set! status 'approved)))
159             (else (error "invalid use case")))
160      output: (status)
161      trans: (((< ships ports) else)))
162
163    (state: else
164      act: (begin (set! status 'approved)
165                  (case use-case
166                    ((arrival) (set! ships (add1 ships)))
167                    ((departure) (set! ships (sub1 ships)))
168                    (else (error "invalid use case"))))
169      output: (status)
170      trans: (((= ports ships) full)
171              ((= ships 0) empty))) ))
172
173
174(docking-control 'departure)
175(denied)
176
177(docking-control 'arrival)
178(approved)
179
180(docking-control 'arrival)
181(approved)
182
183(docking-control 'arrival)
184(approved)
185
186(docking-control 'arrival)
187(denied)
188
189(docking-control 'departure)
190(approved)
191</enscript>
192=== About the Author
193Robert Smiley, the author of this egg can be reached at yarnoiserdev@gmail.com.
Note: See TracBrowser for help on using the repository browser.