| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
|
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2008-2010 -- leonerd@leonerd.org.uk |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package CPS; |
|
7
|
|
|
|
|
|
|
|
|
8
|
16
|
|
|
16
|
|
593897
|
use strict; |
|
|
16
|
|
|
|
|
111
|
|
|
|
16
|
|
|
|
|
379
|
|
|
9
|
16
|
|
|
16
|
|
62
|
use warnings; |
|
|
16
|
|
|
|
|
23
|
|
|
|
16
|
|
|
|
|
490
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = '0.19'; |
|
12
|
|
|
|
|
|
|
|
|
13
|
16
|
|
|
16
|
|
69
|
use Carp; |
|
|
16
|
|
|
|
|
21
|
|
|
|
16
|
|
|
|
|
1576
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our @CPS_PRIMS = qw( |
|
16
|
|
|
|
|
|
|
kloop |
|
17
|
|
|
|
|
|
|
kwhile |
|
18
|
|
|
|
|
|
|
kforeach |
|
19
|
|
|
|
|
|
|
kdescendd kdescendb |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
kpar |
|
22
|
|
|
|
|
|
|
kpareach |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
kseq |
|
25
|
|
|
|
|
|
|
); |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
our @EXPORT_OK = ( |
|
28
|
|
|
|
|
|
|
@CPS_PRIMS, |
|
29
|
|
|
|
|
|
|
map( "g$_", @CPS_PRIMS ), |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
qw( |
|
32
|
|
|
|
|
|
|
liftk |
|
33
|
|
|
|
|
|
|
dropk |
|
34
|
|
|
|
|
|
|
), |
|
35
|
|
|
|
|
|
|
); |
|
36
|
|
|
|
|
|
|
|
|
37
|
16
|
|
|
16
|
|
91
|
use Exporter 'import'; |
|
|
16
|
|
|
|
|
23
|
|
|
|
16
|
|
|
|
|
513
|
|
|
38
|
|
|
|
|
|
|
|
|
39
|
16
|
|
|
16
|
|
5228
|
use CPS::Governor::Simple; |
|
|
16
|
|
|
|
|
29
|
|
|
|
16
|
|
|
|
|
1047
|
|
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Don't hard-depend on Sub::Name since it's only a niceness for stack traces |
|
42
|
|
|
|
|
|
|
BEGIN { |
|
43
|
16
|
50
|
|
16
|
|
41
|
if( eval { require Sub::Name } ) { |
|
|
16
|
|
|
|
|
5828
|
|
|
44
|
16
|
|
|
|
|
22421
|
*subname = \&Sub::Name::subname; |
|
45
|
|
|
|
|
|
|
} |
|
46
|
|
|
|
|
|
|
else { |
|
47
|
|
|
|
|
|
|
# Ignore the name, return the CODEref |
|
48
|
0
|
|
|
|
|
0
|
*subname = sub { return $_[1] }; |
|
|
0
|
|
|
|
|
0
|
|
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 NAME |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
C - manage flow of control in Continuation-Passing Style |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 OVERVIEW |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=over 4 |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
B: This module is entirely deprecated now. It is maintained for |
|
61
|
|
|
|
|
|
|
compatibility for any code still using it, but please consider rewriting to |
|
62
|
|
|
|
|
|
|
use L instead, which offers a far neater method of representing |
|
63
|
|
|
|
|
|
|
asynchronous program and data flow. In addition, L can |
|
64
|
|
|
|
|
|
|
further improve readability of C-based code by letting it use the |
|
65
|
|
|
|
|
|
|
familiar kinds of Perl control structure while still being asynchronous. |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
At some later date this entire C module distribution may be deleted. |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=back |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
The functions in this module implement or assist the writing of programs, or |
|
72
|
|
|
|
|
|
|
parts of them, in Continuation Passing Style (CPS). Briefly, CPS is a style |
|
73
|
|
|
|
|
|
|
of writing code where the normal call/return mechanism is replaced by explicit |
|
74
|
|
|
|
|
|
|
"continuations", values passed in to functions which they should invoke, to |
|
75
|
|
|
|
|
|
|
implement return behaviour. For more detail on CPS, see the SEE ALSO section. |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
What this module implements is not in fact true CPS, as Perl does not natively |
|
78
|
|
|
|
|
|
|
support the idea of a real continuation (such as is created by a co-routine). |
|
79
|
|
|
|
|
|
|
Furthermore, for CPS to be efficient in languages that natively support it, |
|
80
|
|
|
|
|
|
|
their runtimes typically implement a lot of optimisation of CPS code, which |
|
81
|
|
|
|
|
|
|
the Perl interpreter would be unable to perform. Instead, CODE references are |
|
82
|
|
|
|
|
|
|
passed around to stand in their place. While not particularly useful for most |
|
83
|
|
|
|
|
|
|
regular cases, this becomes very useful whenever some form of asynchronous or |
|
84
|
|
|
|
|
|
|
event-based programming is being used. Continuations passed in to the body |
|
85
|
|
|
|
|
|
|
function of a control structure can be stored in the event handlers of the |
|
86
|
|
|
|
|
|
|
asynchronous or event-driven framework, so that when they are invoked later, |
|
87
|
|
|
|
|
|
|
the code continues, eventually arriving at its final answer at some point in |
|
88
|
|
|
|
|
|
|
the future. |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
In order for these examples to make sense, a fictional and simple |
|
91
|
|
|
|
|
|
|
asynchronisation framework has been invented. The exact details of operation |
|
92
|
|
|
|
|
|
|
should not be important, as it simply stands to illustrate the point. I hope |
|
93
|
|
|
|
|
|
|
its general intention should be obvious. :) |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
read_stdin_line( \&on_line ); # wait on a line from STDIN, then pass it |
|
96
|
|
|
|
|
|
|
# to the handler function |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
This module itself provides functions that manage the flow of control through |
|
99
|
|
|
|
|
|
|
a continuation passing program. They do not directly facilitate the flow of |
|
100
|
|
|
|
|
|
|
data through a program. That can be managed by lexical variables captured by |
|
101
|
|
|
|
|
|
|
the closures passed around. See the EXAMPLES section. |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
For CPS versions of data-flow functionals, such as C |
|
104
|
|
|
|
|
|
|
also L. |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
use CPS qw( kloop ); |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
kloop( sub { |
|
111
|
|
|
|
|
|
|
my ( $knext, $klast ) = @_; |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
print "Enter a number, or q to quit: "; |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
read_stdin_line( sub { |
|
116
|
|
|
|
|
|
|
my ( $first ) = @_; |
|
117
|
|
|
|
|
|
|
chomp $first; |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
return $klast->() if $first eq "q"; |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
print "Enter a second number: "; |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
read_stdin_line( sub { |
|
124
|
|
|
|
|
|
|
my ( $second ) = @_; |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
print "The sum is " . ( $first + $second ) . "\n"; |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
$knext->(); |
|
129
|
|
|
|
|
|
|
} ); |
|
130
|
|
|
|
|
|
|
} ); |
|
131
|
|
|
|
|
|
|
}, |
|
132
|
|
|
|
|
|
|
sub { exit } |
|
133
|
|
|
|
|
|
|
); |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=cut |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
In all of the following functions, the C<\&body> function can provide results |
|
140
|
|
|
|
|
|
|
by invoking its continuation / one of its continuations, either synchronously |
|
141
|
|
|
|
|
|
|
or asynchronously at some point later (via some event handling or other |
|
142
|
|
|
|
|
|
|
mechanism); the next invocation of C<\&body> will not take place until the |
|
143
|
|
|
|
|
|
|
previous one exits if it is done synchronously. |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
They all take the prefix C before the name of the regular perl keyword or |
|
146
|
|
|
|
|
|
|
function they aim to replace. It is common in CPS code in other languages, |
|
147
|
|
|
|
|
|
|
such as Scheme or Haskell, to store a continuation in a variable called C. |
|
148
|
|
|
|
|
|
|
This convention is followed here. |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=cut |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 kloop( \&body, $k ) |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
CPS version of perl's C loop. Repeatedly calls the C code |
|
155
|
|
|
|
|
|
|
until it indicates the end of the loop, then invoke C<$k>. |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
$body->( $knext, $klast ) |
|
158
|
|
|
|
|
|
|
$knext->() |
|
159
|
|
|
|
|
|
|
$klast->() |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
$k->() |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
If C<$knext> is invoked, the body will be called again. If C<$klast> is |
|
164
|
|
|
|
|
|
|
invoked, the continuation C<$k> is invoked. |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 kwhile( \&body, $k ) |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Compatibility synonym for C; it was renamed after version 0.10. New |
|
169
|
|
|
|
|
|
|
code should use C instead. |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=cut |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub _fix |
|
174
|
|
|
|
|
|
|
{ |
|
175
|
112
|
|
|
112
|
|
141
|
my ( $func ) = @_; |
|
176
|
|
|
|
|
|
|
sub { |
|
177
|
89
|
|
|
89
|
|
130
|
unshift @_, _fix( $func ); |
|
178
|
89
|
|
|
|
|
224
|
goto &$func; |
|
179
|
112
|
|
|
|
|
285
|
}; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub gkloop |
|
183
|
|
|
|
|
|
|
{ |
|
184
|
23
|
|
|
23
|
0
|
58
|
my ( $gov, $body, $k ) = @_; |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# We can't just call this as a method because we need to tailcall it |
|
187
|
|
|
|
|
|
|
# Instead, keep a reference to the actual method so we can goto &$enter |
|
188
|
23
|
50
|
|
|
|
144
|
my $enter = $gov->can('enter') or croak "Governor cannot ->enter"; |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
my $kfirst = _fix subname gkloop => sub { |
|
191
|
89
|
|
|
89
|
|
107
|
my $knext = shift; |
|
192
|
|
|
|
|
|
|
|
|
193
|
89
|
|
|
|
|
95
|
my $sync = 1; |
|
194
|
89
|
|
|
|
|
87
|
my $do_again; |
|
195
|
|
|
|
|
|
|
$enter->( $gov, $body, |
|
196
|
|
|
|
|
|
|
sub { |
|
197
|
66
|
100
|
|
|
|
2580
|
if( $sync ) { $do_again=1 } |
|
|
60
|
|
|
|
|
122
|
|
|
198
|
6
|
|
|
|
|
13
|
else { goto &$knext; } |
|
199
|
|
|
|
|
|
|
}, |
|
200
|
23
|
|
|
|
|
938
|
sub { @_ = (); goto &$k }, |
|
|
23
|
|
|
|
|
42
|
|
|
201
|
89
|
|
|
|
|
330
|
); |
|
202
|
89
|
|
|
|
|
301
|
$sync = 0; |
|
203
|
|
|
|
|
|
|
|
|
204
|
89
|
100
|
|
|
|
246
|
if( $do_again ) { |
|
205
|
60
|
|
|
|
|
57
|
$do_again = 0; |
|
206
|
60
|
|
|
|
|
97
|
goto &$knext; |
|
207
|
|
|
|
|
|
|
} |
|
208
|
23
|
|
|
|
|
192
|
}; |
|
209
|
|
|
|
|
|
|
|
|
210
|
23
|
|
|
|
|
55
|
goto &$kfirst; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
*gkwhile = \&gkloop; |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=head2 kforeach( \@items, \&body, $k ) |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
CPS version of perl's C loop. Calls the C code once for each |
|
218
|
|
|
|
|
|
|
element in C<@items>, until either the items are exhausted or the C |
|
219
|
|
|
|
|
|
|
invokes its C<$klast> continuation, then invoke C<$k>. |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
$body->( $item, $knext, $klast ) |
|
222
|
|
|
|
|
|
|
$knext->() |
|
223
|
|
|
|
|
|
|
$klast->() |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
$k->() |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub gkforeach |
|
230
|
|
|
|
|
|
|
{ |
|
231
|
10
|
|
|
10
|
0
|
666
|
my ( $gov, $items, $body, $k ) = @_; |
|
232
|
|
|
|
|
|
|
|
|
233
|
10
|
|
|
|
|
14
|
my $idx = 0; |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
gkloop( $gov, |
|
236
|
|
|
|
|
|
|
sub { |
|
237
|
35
|
|
|
35
|
|
59
|
my ( $knext, $klast ) = @_; |
|
238
|
35
|
100
|
|
|
|
68
|
goto &$klast unless $idx < scalar @$items; |
|
239
|
26
|
|
|
|
|
48
|
@_ =( |
|
240
|
|
|
|
|
|
|
$items->[$idx++], |
|
241
|
|
|
|
|
|
|
$knext, |
|
242
|
|
|
|
|
|
|
$klast |
|
243
|
|
|
|
|
|
|
); |
|
244
|
26
|
|
|
|
|
46
|
goto &$body; |
|
245
|
|
|
|
|
|
|
}, |
|
246
|
10
|
|
|
|
|
39
|
$k, |
|
247
|
|
|
|
|
|
|
); |
|
248
|
|
|
|
|
|
|
} |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head2 kdescendd( $root, \&body, $k ) |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
CPS version of recursive descent on a tree-like structure, defined by a |
|
253
|
|
|
|
|
|
|
function, C, which when given a node in the tree, yields a list of |
|
254
|
|
|
|
|
|
|
child nodes. |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
$body->( $node, $kmore ) |
|
257
|
|
|
|
|
|
|
$kmore->( @child_nodes ) |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
$k->() |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
The first value to be passed into C is C<$root>. |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
At each iteration, a node is given to the C function, and it is expected |
|
264
|
|
|
|
|
|
|
to pass a list of child nodes into its C<$kmore> continuation. These will then |
|
265
|
|
|
|
|
|
|
be iterated over, in the order given. The tree-like structure is visited |
|
266
|
|
|
|
|
|
|
depth-first, descending fully into one subtree of a node before moving on to |
|
267
|
|
|
|
|
|
|
the next. |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
This function does not provide a way for the body to accumulate a resultant |
|
270
|
|
|
|
|
|
|
data structure to pass into its own continuation. The body is executed simply |
|
271
|
|
|
|
|
|
|
for its side-effects and its continuation is invoked with no arguments. A |
|
272
|
|
|
|
|
|
|
variable of some sort should be shared between the body and the continuation |
|
273
|
|
|
|
|
|
|
if this is required. |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub gkdescendd |
|
278
|
|
|
|
|
|
|
{ |
|
279
|
1
|
|
|
1
|
0
|
2
|
my ( $gov, $root, $body, $k ) = @_; |
|
280
|
|
|
|
|
|
|
|
|
281
|
1
|
|
|
|
|
3
|
my @stack = ( $root ); |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
gkloop( $gov, |
|
284
|
|
|
|
|
|
|
sub { |
|
285
|
9
|
|
|
9
|
|
12
|
my ( $knext, $klast ) = @_; |
|
286
|
|
|
|
|
|
|
@_ = ( |
|
287
|
|
|
|
|
|
|
shift @stack, |
|
288
|
|
|
|
|
|
|
sub { |
|
289
|
9
|
|
|
|
|
39
|
unshift @stack, @_; |
|
290
|
|
|
|
|
|
|
|
|
291
|
9
|
100
|
|
|
|
16
|
goto &$knext if @stack; |
|
292
|
1
|
|
|
|
|
2
|
goto &$klast; |
|
293
|
|
|
|
|
|
|
}, |
|
294
|
9
|
|
|
|
|
18
|
); |
|
295
|
9
|
|
|
|
|
18
|
goto &$body; |
|
296
|
|
|
|
|
|
|
}, |
|
297
|
1
|
|
|
|
|
7
|
$k, |
|
298
|
|
|
|
|
|
|
); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head2 kdescendb( $root, \&body, $k ) |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
A breadth-first variation of C. This function visits each child |
|
304
|
|
|
|
|
|
|
node of the parent, before iterating over all of these nodes's children, |
|
305
|
|
|
|
|
|
|
recursively until the bottom of the tree. |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=cut |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub gkdescendb |
|
310
|
|
|
|
|
|
|
{ |
|
311
|
1
|
|
|
1
|
0
|
3
|
my ( $gov, $root, $body, $k ) = @_; |
|
312
|
|
|
|
|
|
|
|
|
313
|
1
|
|
|
|
|
2
|
my @queue = ( $root ); |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
gkloop( $gov, |
|
316
|
|
|
|
|
|
|
sub { |
|
317
|
9
|
|
|
9
|
|
11
|
my ( $knext, $klast ) = @_; |
|
318
|
|
|
|
|
|
|
@_ = ( |
|
319
|
|
|
|
|
|
|
shift @queue, |
|
320
|
|
|
|
|
|
|
sub { |
|
321
|
9
|
|
|
|
|
38
|
push @queue, @_; |
|
322
|
|
|
|
|
|
|
|
|
323
|
9
|
100
|
|
|
|
18
|
goto &$knext if @queue; |
|
324
|
1
|
|
|
|
|
2
|
goto &$klast; |
|
325
|
|
|
|
|
|
|
}, |
|
326
|
9
|
|
|
|
|
21
|
); |
|
327
|
9
|
|
|
|
|
12
|
goto &$body; |
|
328
|
|
|
|
|
|
|
}, |
|
329
|
1
|
|
|
|
|
5
|
$k, |
|
330
|
|
|
|
|
|
|
); |
|
331
|
|
|
|
|
|
|
} |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head2 kpar( @bodies, $k ) |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
This CPS function takes a list of function bodies and calls them all |
|
336
|
|
|
|
|
|
|
immediately. Each is given its own continuation. Once every body has invoked |
|
337
|
|
|
|
|
|
|
its continuation, the main continuation C<$k> is invoked. |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
$body->( $kdone ) |
|
340
|
|
|
|
|
|
|
$kdone->() |
|
341
|
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
$k->() |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
This allows running multiple operations in parallel, and waiting for them all |
|
345
|
|
|
|
|
|
|
to complete before continuing. It provides in a CPS form functionality |
|
346
|
|
|
|
|
|
|
similar to that provided in a more object-oriented fashion by modules such as |
|
347
|
|
|
|
|
|
|
L or L. |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=cut |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub gkpar |
|
352
|
|
|
|
|
|
|
{ |
|
353
|
5
|
|
|
5
|
0
|
11
|
my ( $gov, @bodies ) = @_; |
|
354
|
5
|
|
|
|
|
9
|
my $k = pop @bodies; |
|
355
|
|
|
|
|
|
|
|
|
356
|
5
|
50
|
|
|
|
29
|
$gov->can('enter') or croak "Governor cannot ->enter"; |
|
357
|
|
|
|
|
|
|
|
|
358
|
5
|
|
|
|
|
7
|
my $sync = 1; |
|
359
|
5
|
|
|
|
|
5
|
my @outstanding; |
|
360
|
|
|
|
|
|
|
my $kdone = sub { |
|
361
|
14
|
100
|
|
14
|
|
26
|
return if $sync; |
|
362
|
9
|
|
100
|
|
|
28
|
$_ and return for @outstanding; |
|
363
|
5
|
|
|
|
|
8
|
goto &$k; |
|
364
|
5
|
|
|
|
|
13
|
}; |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
gkforeach( $gov, [ 0 .. $#bodies ], |
|
367
|
|
|
|
|
|
|
sub { |
|
368
|
9
|
|
|
9
|
|
12
|
my ( $idx, $knext ) = @_; |
|
369
|
9
|
|
|
|
|
13
|
$outstanding[$idx]++; |
|
370
|
|
|
|
|
|
|
$gov->enter( $bodies[$idx], sub { |
|
371
|
9
|
|
|
|
|
2638
|
$outstanding[$idx]--; |
|
372
|
9
|
|
|
|
|
12
|
@_ = (); |
|
373
|
9
|
|
|
|
|
16
|
goto &$kdone; |
|
374
|
9
|
|
|
|
|
33
|
} ); |
|
375
|
9
|
|
|
|
|
27
|
goto &$knext; |
|
376
|
|
|
|
|
|
|
}, |
|
377
|
|
|
|
|
|
|
sub { |
|
378
|
5
|
|
|
5
|
|
6
|
$sync = 0; |
|
379
|
5
|
|
|
|
|
6
|
@_ = (); |
|
380
|
5
|
|
|
|
|
16
|
goto &$kdone; |
|
381
|
|
|
|
|
|
|
} |
|
382
|
5
|
|
|
|
|
28
|
); |
|
383
|
|
|
|
|
|
|
} |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=head2 kpareach( \@items, \&body, $k ) |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
This CPS function takes a list of items and a function body, and calls the |
|
388
|
|
|
|
|
|
|
body immediately once for each item in the list. Each invocation is given its |
|
389
|
|
|
|
|
|
|
own continuation. Once every body has invoked its continuation, the main |
|
390
|
|
|
|
|
|
|
continuation C<$k> is invoked. |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
$body->( $item, $kdone ) |
|
393
|
|
|
|
|
|
|
$kdone->() |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
$k->() |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
This is similar to C, except that the body is started concurrently |
|
398
|
|
|
|
|
|
|
for all items in the list list, rather than each item waiting for the previous |
|
399
|
|
|
|
|
|
|
to finish. |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=cut |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
sub gkpareach |
|
404
|
|
|
|
|
|
|
{ |
|
405
|
2
|
|
|
2
|
0
|
5
|
my ( $gov, $items, $body, $k ) = @_; |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
gkpar( $gov, |
|
408
|
|
|
|
|
|
|
(map { |
|
409
|
2
|
|
|
|
|
4
|
my $item = $_; |
|
|
4
|
|
|
|
|
5
|
|
|
410
|
|
|
|
|
|
|
sub { |
|
411
|
4
|
|
|
4
|
|
7
|
unshift @_, $item; |
|
412
|
4
|
|
|
|
|
6
|
goto &$body |
|
413
|
|
|
|
|
|
|
} |
|
414
|
4
|
|
|
|
|
16
|
} @$items), |
|
415
|
|
|
|
|
|
|
$k |
|
416
|
|
|
|
|
|
|
); |
|
417
|
|
|
|
|
|
|
} |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=head2 kseq( @bodies, $k ) |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
This CPS function takes a list of function bodies and calls them each, one at |
|
422
|
|
|
|
|
|
|
a time in sequence. Each is given a continuation to invoke, which will cause |
|
423
|
|
|
|
|
|
|
the next body to be invoked. When the last body has invoked its continuation, |
|
424
|
|
|
|
|
|
|
the main continuation C<$k> is invoked. |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
$body->( $kdone ) |
|
427
|
|
|
|
|
|
|
$kdone->() |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
$k->() |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
A benefit of this is that it allows a long operation that uses many |
|
432
|
|
|
|
|
|
|
continuation "pauses", to be written without code indenting further and |
|
433
|
|
|
|
|
|
|
further to the right. Another is that it allows easy skipping of conditional |
|
434
|
|
|
|
|
|
|
parts of a computation, which would otherwise be tricky to write in a CPS |
|
435
|
|
|
|
|
|
|
form. See the EXAMPLES section. |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=cut |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub gkseq |
|
440
|
|
|
|
|
|
|
{ |
|
441
|
2
|
|
|
2
|
0
|
5
|
my ( $gov, @bodies ) = @_; |
|
442
|
2
|
|
|
|
|
3
|
my $k = pop @bodies; |
|
443
|
|
|
|
|
|
|
|
|
444
|
2
|
50
|
|
|
|
15
|
my $enter = $gov->can('enter') or croak "Governor cannot ->enter"; |
|
445
|
|
|
|
|
|
|
|
|
446
|
2
|
|
|
|
|
5
|
while( @bodies ) { |
|
447
|
4
|
|
|
|
|
4
|
my $nextk = $k; |
|
448
|
4
|
|
|
|
|
5
|
my $b = pop @bodies; |
|
449
|
|
|
|
|
|
|
$k = sub { |
|
450
|
4
|
|
|
4
|
|
900
|
@_ = ( $gov, $b, $nextk ); |
|
451
|
4
|
|
|
|
|
15
|
goto &$enter; |
|
452
|
4
|
|
|
|
|
12
|
}; |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
|
|
455
|
2
|
|
|
|
|
4
|
@_ = (); |
|
456
|
2
|
|
|
|
|
4
|
goto &$k; |
|
457
|
|
|
|
|
|
|
} |
|
458
|
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head1 GOVERNORS |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
All of the above functions are implemented using a loop which repeatedly calls |
|
462
|
|
|
|
|
|
|
the body function until some terminating condition. By controlling the way |
|
463
|
|
|
|
|
|
|
this loop re-invokes itself, a program can control the behaviour of the |
|
464
|
|
|
|
|
|
|
functions. |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
For every one of the above functions, there also exists a variant which takes |
|
467
|
|
|
|
|
|
|
a L object as its first argument. These functions use the |
|
468
|
|
|
|
|
|
|
governor object to control their iteration. |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
kloop( \&body, $k ) |
|
471
|
|
|
|
|
|
|
gkloop( $gov, \&body, $k ) |
|
472
|
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
kforeach( \@items, \&body, $k ) |
|
474
|
|
|
|
|
|
|
gkforeach( $gov, \@items, \&body, $k ) |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
etc... |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
In this way, other governor objects can be constructed which have different |
|
479
|
|
|
|
|
|
|
running properties; such as interleaving iterations of their loop with other |
|
480
|
|
|
|
|
|
|
IO activity in an event-driven framework, or giving rate-limitation control on |
|
481
|
|
|
|
|
|
|
the speed of iteration of the loop. |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=cut |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
# The above is a lie. The basic functions provided are actually the gk* |
|
486
|
|
|
|
|
|
|
# versions; we wrap these to make the normal k* functions by passing a simple |
|
487
|
|
|
|
|
|
|
# governor. |
|
488
|
|
|
|
|
|
|
sub _governate |
|
489
|
|
|
|
|
|
|
{ |
|
490
|
153
|
|
|
153
|
|
228
|
my $pkg = caller; |
|
491
|
153
|
|
|
|
|
212
|
my ( $func, $name ) = @_; |
|
492
|
|
|
|
|
|
|
|
|
493
|
153
|
|
|
|
|
328
|
my $default_gov = CPS::Governor::Simple->new; |
|
494
|
|
|
|
|
|
|
|
|
495
|
16
|
|
|
16
|
|
152
|
no strict 'refs'; |
|
|
16
|
|
|
|
|
26
|
|
|
|
16
|
|
|
|
|
4672
|
|
|
496
|
|
|
|
|
|
|
|
|
497
|
153
|
50
|
|
|
|
429
|
my $code = $pkg->can( $func ) or croak "$pkg cannot $func()"; |
|
498
|
153
|
|
|
|
|
649
|
*{$pkg."::$name"} = subname $name => sub { |
|
499
|
22
|
|
|
22
|
1
|
7274
|
unshift @_, $default_gov; |
|
|
|
|
|
22
|
1
|
|
|
|
|
|
|
|
22
|
1
|
|
|
|
|
|
|
|
5
|
1
|
|
|
|
|
|
|
|
5
|
1
|
|
|
|
|
|
|
|
22
|
1
|
|
|
|
|
|
|
|
5
|
1
|
|
|
|
|
|
|
|
22
|
1
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
500
|
22
|
|
|
|
|
78
|
goto &$code; |
|
501
|
153
|
|
|
|
|
626
|
}; |
|
502
|
|
|
|
|
|
|
} |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
_governate "g$_" => $_ for @CPS_PRIMS; |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head1 CPS UTILITIES |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
These function names do not begin with C because they are not themselves |
|
509
|
|
|
|
|
|
|
CPS primatives, but may be useful in CPS-oriented code. |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=cut |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=head2 $kfunc = liftk { BLOCK } |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head2 $kfunc = liftk( \&func ) |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
Returns a new CODE reference to a CPS-wrapped version of the code block or |
|
518
|
|
|
|
|
|
|
passed CODE reference. When C<$kfunc> is invoked, the function C<&func> is |
|
519
|
|
|
|
|
|
|
called in list context, being passed all the arguments given to C<$kfunc> |
|
520
|
|
|
|
|
|
|
apart from the last, expected to be its continuation. When C<&func> returns, |
|
521
|
|
|
|
|
|
|
the result is passed into the continuation. |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
$kfunc->( @func_args, $k ) |
|
524
|
|
|
|
|
|
|
$k->( @func_ret ) |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
The following are equivalent |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
print func( 1, 2, 3 ); |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
my $kfunc = liftk( \&func ); |
|
531
|
|
|
|
|
|
|
$kfunc->( 1, 2, 3, sub { print @_ } ); |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
Note that the returned wrapper function only has one continuation slot in its |
|
534
|
|
|
|
|
|
|
arguments. It therefore cannot be used as the body for C, |
|
535
|
|
|
|
|
|
|
C or C, because these pass two continuations. There |
|
536
|
|
|
|
|
|
|
does not exist a "natural" way to lift a normal call/return function into a |
|
537
|
|
|
|
|
|
|
CPS function which requires more than one continuation, because there is no |
|
538
|
|
|
|
|
|
|
way to distinguish the different named returns. |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=cut |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
sub liftk(&) |
|
543
|
|
|
|
|
|
|
{ |
|
544
|
3
|
|
|
3
|
1
|
917
|
my ( $code ) = @_; |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
return sub { |
|
547
|
3
|
|
|
3
|
|
646
|
my $k = pop; |
|
548
|
3
|
|
|
|
|
9
|
@_ = $code->( @_ ); |
|
549
|
3
|
|
|
|
|
18
|
goto &$k; |
|
550
|
3
|
|
|
|
|
13
|
}; |
|
551
|
|
|
|
|
|
|
} |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=head2 $func = dropk { BLOCK } $kfunc |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=head2 $func = dropk $waitfunc, $kfunc |
|
556
|
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
Returns a new CODE reference to a plain call/return version of the passed |
|
558
|
|
|
|
|
|
|
CPS-style CODE reference. When the returned ("dropped") function is called, |
|
559
|
|
|
|
|
|
|
it invokes the passed CPS function, then waits for it to invoke its |
|
560
|
|
|
|
|
|
|
continuation. When it does, the list that was passed to the continuation is |
|
561
|
|
|
|
|
|
|
returned by the dropped function. If called in scalar context, only the first |
|
562
|
|
|
|
|
|
|
value in the list is returned. |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
$kfunc->( @func_args, $k ) |
|
565
|
|
|
|
|
|
|
$k->( @func_ret ) |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
$waitfunc->() |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
@func_ret = $func->( @func_args ) |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
Given the following trivial CPS function: |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
$kadd = sub { $_[2]->( $_[0] + $_[1] ) }; |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
The following are equivalent |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
$kadd->( 10, 20, sub { print "The total is $_[0]\n" } ); |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
$add = dropk { } $kadd; |
|
580
|
|
|
|
|
|
|
print "The total is ".$add->( 10, 20 )."\n"; |
|
581
|
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
In the general case the CPS function hasn't yet invoked its continuation by |
|
583
|
|
|
|
|
|
|
the time it returns (such as would be the case when using any sort of |
|
584
|
|
|
|
|
|
|
asynchronisation or event-driven framework). For C to actually work in |
|
585
|
|
|
|
|
|
|
this situation, it requires a way to run the event framework, to cause it to |
|
586
|
|
|
|
|
|
|
process events until the continuation has been invoked. |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
This is provided by the block, or the first passed CODE reference. When the |
|
589
|
|
|
|
|
|
|
returned function is invoked, it repeatedly calls the block or wait function, |
|
590
|
|
|
|
|
|
|
until the CPS function has invoked its continuation. |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
=cut |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
sub dropk(&$) |
|
595
|
|
|
|
|
|
|
{ |
|
596
|
2
|
|
|
2
|
1
|
511
|
my ( $waitfunc, $kfunc ) = @_; |
|
597
|
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
return sub { |
|
599
|
3
|
|
|
3
|
|
1096
|
my @result; |
|
600
|
|
|
|
|
|
|
my $done; |
|
601
|
|
|
|
|
|
|
|
|
602
|
3
|
|
|
|
|
37
|
$kfunc->( @_, sub { @result = @_; $done = 1 } ); |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
6
|
|
|
603
|
|
|
|
|
|
|
|
|
604
|
3
|
|
|
|
|
20
|
while( !$done ) { |
|
605
|
2
|
|
|
|
|
4
|
$waitfunc->(); |
|
606
|
|
|
|
|
|
|
} |
|
607
|
|
|
|
|
|
|
|
|
608
|
3
|
100
|
|
|
|
8
|
return wantarray ? @result : $result[0]; |
|
609
|
|
|
|
|
|
|
} |
|
610
|
2
|
|
|
|
|
8
|
} |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=head1 EXAMPLES |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=head2 Returning Data From Functions |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
No facilities are provided directly to return data from CPS body functions in |
|
617
|
|
|
|
|
|
|
C, C and C. Instead, normal lexical variable capture may |
|
618
|
|
|
|
|
|
|
be used here. |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
my $bat; |
|
621
|
|
|
|
|
|
|
my $ball; |
|
622
|
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
kpar( |
|
624
|
|
|
|
|
|
|
sub { |
|
625
|
|
|
|
|
|
|
my ( $k ) = @_; |
|
626
|
|
|
|
|
|
|
get_bat( on_bat => sub { $bat = shift; goto &$k } ); |
|
627
|
|
|
|
|
|
|
}, |
|
628
|
|
|
|
|
|
|
sub { |
|
629
|
|
|
|
|
|
|
my ( $k ) = @_; |
|
630
|
|
|
|
|
|
|
serve_ball( on_ball => sub { $ball = shift; goto &$k } ); |
|
631
|
|
|
|
|
|
|
}, |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
sub { |
|
634
|
|
|
|
|
|
|
$bat->hit( $ball ); |
|
635
|
|
|
|
|
|
|
}, |
|
636
|
|
|
|
|
|
|
); |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
The body function can set the value of a variable that it and its final |
|
639
|
|
|
|
|
|
|
continuation both capture. |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
=head2 Using C For Conditionals |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
Consider the call/return style of code |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
A(); |
|
646
|
|
|
|
|
|
|
if( $maybe ) { |
|
647
|
|
|
|
|
|
|
B(); |
|
648
|
|
|
|
|
|
|
} |
|
649
|
|
|
|
|
|
|
C(); |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
We cannot easily write this in CPS form without naming C twice |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
kA( sub { |
|
654
|
|
|
|
|
|
|
$maybe ? |
|
655
|
|
|
|
|
|
|
kB( sub { kC() } ) : |
|
656
|
|
|
|
|
|
|
kC(); |
|
657
|
|
|
|
|
|
|
} ); |
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
While not so problematic here, it could get awkward if C were in fact a large |
|
660
|
|
|
|
|
|
|
code block, or if more than a single conditional were employed in the logic; a |
|
661
|
|
|
|
|
|
|
likely scenario. A further issue is that the logical structure becomes much |
|
662
|
|
|
|
|
|
|
harder to read. |
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
Using C allows us to name the continuation so each arm of C can |
|
665
|
|
|
|
|
|
|
invoke it indirectly. |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
kseq( |
|
668
|
|
|
|
|
|
|
\&kA, |
|
669
|
|
|
|
|
|
|
sub { my $k = shift; $maybe ? kB( $k ) : goto &$k; }, |
|
670
|
|
|
|
|
|
|
\&kC |
|
671
|
|
|
|
|
|
|
); |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=over 4 |
|
676
|
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=item * |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
L - represent an operation awaiting completion |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
=item * |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
L - deferred subroutine syntax for futures |
|
684
|
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=item * |
|
686
|
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
L - functional utilities in Continuation-Passing Style |
|
688
|
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
=item * |
|
690
|
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
L on wikipedia |
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=back |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
|
696
|
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
Matt S. Trout (mst) - for the inspiration of C |
|
698
|
|
|
|
|
|
|
and with apologies to for naming of the said. ;) |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=head1 AUTHOR |
|
701
|
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
Paul Evans |
|
703
|
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
=cut |
|
705
|
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
0x55AA; |