1Future::Utils(3) User Contributed Perl Documentation Future::Utils(3)
2
3
4
6 "Future::Utils" - utility functions for working with "Future" objects
7
9 use Future::Utils qw( call_with_escape );
10
11 my $result_f = call_with_escape {
12 my $escape_f = shift;
13 my $f = ...
14 $escape_f->done( "immediate result" );
15 ...
16 };
17
18 use Future::Utils qw( repeat try_repeat try_repeat_until_success );
19
20 my $eventual_f = repeat {
21 my $trial_f = ...
22 return $trial_f;
23 } while => sub { my $f = shift; return want_more($f) };
24
25 my $eventual_f = repeat {
26 ...
27 return $trial_f;
28 } until => sub { my $f = shift; return acceptable($f) };
29
30 my $eventual_f = repeat {
31 my $item = shift;
32 ...
33 return $trial_f;
34 } foreach => \@items;
35
36 my $eventual_f = try_repeat {
37 my $trial_f = ...
38 return $trial_f;
39 } while => sub { ... };
40
41 my $eventual_f = try_repeat_until_success {
42 ...
43 return $trial_f;
44 };
45
46 my $eventual_f = try_repeat_until_success {
47 my $item = shift;
48 ...
49 return $trial_f;
50 } foreach => \@items;
51
52 use Future::Utils qw( fmap_concat fmap_scalar fmap_void );
53
54 my $result_f = fmap_concat {
55 my $item = shift;
56 ...
57 return $item_f;
58 } foreach => \@items, concurrent => 4;
59
60 my $result_f = fmap_scalar {
61 my $item = shift;
62 ...
63 return $item_f;
64 } foreach => \@items, concurrent => 8;
65
66 my $done_f = fmap_void {
67 my $item = shift;
68 ...
69 return $item_f;
70 } foreach => \@items, concurrent => 10;
71
72 Unless otherwise noted, the following functions require at least
73 version 0.08.
74
76 call
77 $f = call { CODE }
78
79 Since version 0.22.
80
81 The "call" function invokes a block of code that returns a future, and
82 simply returns the future it returned. The code is wrapped in an "eval
83 {}" block, so that if it throws an exception this is turned into an
84 immediate failed "Future". If the code does not return a "Future", then
85 an immediate failed "Future" instead.
86
87 (This is equivalent to using "Future->call", but is duplicated here for
88 completeness).
89
90 call_with_escape
91 $f = call_with_escape { CODE }
92
93 Since version 0.22.
94
95 The "call_with_escape" function invokes a block of code that returns a
96 future, and passes in a separate future (called here an "escape
97 future"). Normally this is equivalent to the simple "call" function.
98 However, if the code captures this future and completes it by calling
99 "done" or "fail" on it, the future returned by "call_with_escape"
100 immediately completes with this result, and the future returned by the
101 code itself is cancelled.
102
103 This can be used to implement short-circuit return from an iterating
104 loop or complex sequence of code, or immediate fail that bypasses
105 failure handling logic in the code itself, or several other code
106 patterns.
107
108 $f = $code->( $escape_f )
109
110 (This can be considered similar to "call-with-escape-continuation" as
111 found in some Scheme implementations).
112
114 The "repeat" function provides a way to repeatedly call a block of code
115 that returns a Future (called here a "trial future") until some ending
116 condition is satisfied. The "repeat" function itself returns a "Future"
117 to represent running the repeating loop until that end condition
118 (called here the "eventual future"). The first time the code block is
119 called, it is passed no arguments, and each subsequent invocation is
120 passed the previous trial future.
121
122 The result of the eventual future is the result of the last trial
123 future.
124
125 If the eventual future is cancelled, the latest trial future will be
126 cancelled.
127
128 If some specific subclass or instance of "Future" is required as the
129 return value, it can be passed as the "return" argument. Otherwise the
130 return value will be constructed by cloning the first non-immediate
131 trial "Future".
132
133 repeat+while
134 $future = repeat { CODE } while => CODE
135
136 Repeatedly calls the "CODE" block while the "while" condition returns a
137 true value. Each time the trial future completes, the "while" condition
138 is passed the trial future.
139
140 $trial_f = $code->( $previous_trial_f )
141 $again = $while->( $trial_f )
142
143 If the $code block dies entirely and throws an exception, this will be
144 caught and considered as an immediately-failed "Future" with the
145 exception as the future's failure. The exception will not be propagated
146 to the caller.
147
148 repeat+until
149 $future = repeat { CODE } until => CODE
150
151 Repeatedly calls the "CODE" block until the "until" condition returns a
152 true value. Each time the trial future completes, the "until" condition
153 is passed the trial future.
154
155 $trial_f = $code->( $previous_trial_f )
156 $accept = $until->( $trial_f )
157
158 repeat+foreach
159 $future = repeat { CODE } foreach => ARRAY, otherwise => CODE
160
161 Since version 0.13.
162
163 Calls the "CODE" block once for each value obtained from the array,
164 passing in the value as the first argument (before the previous trial
165 future). When there are no more items left in the array, the
166 "otherwise" code is invoked once and passed the last trial future, if
167 there was one, or "undef" if the list was originally empty. The result
168 of the eventual future will be the result of the future returned from
169 "otherwise".
170
171 The referenced array may be modified by this operation.
172
173 $trial_f = $code->( $item, $previous_trial_f )
174 $final_f = $otherwise->( $last_trial_f )
175
176 The "otherwise" code is optional; if not supplied then the result of
177 the eventual future will simply be that of the last trial. If there was
178 no trial, because the "foreach" list was already empty, then an
179 immediate successful future with an empty result is returned.
180
181 repeat+foreach+while
182 $future = repeat { CODE } foreach => ARRAY, while => CODE, ...
183
184 Since version 0.13.
185
186 repeat+foreach+until
187 $future = repeat { CODE } foreach => ARRAY, until => CODE, ...
188
189 Since version 0.13.
190
191 Combines the effects of "foreach" with "while" or "until". Calls the
192 "CODE" block once for each value obtained from the array, until the
193 array is exhausted or the given ending condition is satisfied.
194
195 If a "while" or "until" condition is combined with "otherwise", the
196 "otherwise" code will only be run if the array was entirely exhausted.
197 If the operation is terminated early due to the "while" or "until"
198 condition being satisfied, the eventual result will simply be that of
199 the last trial that was executed.
200
201 repeat+generate
202 $future = repeat { CODE } generate => CODE, otherwise => CODE
203
204 Since version 0.13.
205
206 Calls the "CODE" block once for each value obtained from the generator
207 code, passing in the value as the first argument (before the previous
208 trial future). When the generator returns an empty list, the
209 "otherwise" code is invoked and passed the last trial future, if there
210 was one, otherwise "undef" if the generator never returned a value. The
211 result of the eventual future will be the result of the future returned
212 from "otherwise".
213
214 $trial_f = $code->( $item, $previous_trial_f )
215 $final_f = $otherwise->( $last_trial_f )
216
217 ( $item ) = $generate->()
218
219 The generator is called in list context but should return only one item
220 per call. Subsequent values will be ignored. When it has no more items
221 to return it should return an empty list.
222
223 For backward compatibility this function will allow a "while" or
224 "until" condition that requests a failure be repeated, but it will
225 print a warning if it has to do that. To apply repeating behaviour that
226 can catch and retry failures, use "try_repeat" instead. This old
227 behaviour is now deprecated and will be removed in the next version.
228
229 try_repeat
230 $future = try_repeat { CODE } ...
231
232 Since version 0.18.
233
234 A variant of "repeat" that doesn't warn when the trial fails and the
235 condition code asks for it to be repeated.
236
237 In some later version the "repeat" function will be changed so that if
238 a trial future fails, then the eventual future will immediately fail as
239 well, making its semantics a little closer to that of a "while {}" loop
240 in Perl. Code that specifically wishes to catch failures in trial
241 futures and retry the block should use "try_repeat" specifically.
242
243 try_repeat_until_success
244 $future = try_repeat_until_success { CODE } ...
245
246 Since version 0.18.
247
248 A shortcut to calling "try_repeat" with an ending condition that simply
249 tests for a successful result from a future. May be combined with
250 "foreach" or "generate".
251
252 This function used to be called "repeat_until_success", and is
253 currently aliased as this name as well.
254
256 The "fmap" family of functions provide a way to call a block of code
257 that returns a Future (called here an "item future") once per item in a
258 given list, or returned by a generator function. The "fmap*" functions
259 themselves return a "Future" to represent the ongoing operation, which
260 completes when every item's future has completed.
261
262 While this behaviour can also be implemented using "repeat", the main
263 reason to use an "fmap" function is that the individual item operations
264 are considered as independent, and thus more than one can be
265 outstanding concurrently. An argument can be passed to the function to
266 indicate how many items to start initially, and thereafter it will keep
267 that many of them running concurrently until all of the items are done,
268 or until any of them fail. If an individual item future fails, the
269 overall result future will be marked as failing with the same failure,
270 and any other pending item futures that are outstanding at the time
271 will be cancelled.
272
273 The following named arguments are common to each "fmap*" function:
274
275 foreach => ARRAY
276 Provides the list of items to iterate over, as an "ARRAY"
277 reference.
278
279 The referenced array will be modified by this operation,
280 "shift"ing one item from it each time. The can "push" more
281 items to this array as it runs, and they will be included in
282 the iteration.
283
284 generate => CODE
285 Provides the list of items to iterate over, by calling the
286 generator function once for each required item. The function
287 should return a single item, or an empty list to indicate it
288 has no more items.
289
290 ( $item ) = $generate->()
291
292 This function will be invoked each time any previous item
293 future has completed and may be called again even after it has
294 returned empty.
295
296 concurrent => INT
297 Gives the number of item futures to keep outstanding. By
298 default this value will be 1 (i.e. no concurrency); larger
299 values indicate that multiple item futures will be started at
300 once.
301
302 return => Future
303 Normally, a new instance is returned by cloning the first non-
304 immediate future returned as an item future. By passing a new
305 instance as the "return" argument, the result will be put into
306 the given instance. This can be used to return subclasses, or
307 specific instances.
308
309 In each case, the main code block will be called once for each item in
310 the list, passing in the item as the only argument:
311
312 $item_f = $code->( $item )
313
314 The expected return value from each item's future, and the value
315 returned from the result future will differ in each function's case;
316 they are documented below.
317
318 For similarity with perl's core "map" function, the item is also
319 available aliased as $_.
320
321 fmap_concat
322 $future = fmap_concat { CODE } ...
323
324 Since version 0.14.
325
326 This version of "fmap" expects each item future to return a list of
327 zero or more values, and the overall result will be the concatenation
328 of all these results. It acts like a future-based equivalent to Perl's
329 "map" operator.
330
331 The results are returned in the order of the original input values, not
332 in the order their futures complete in. Because of the intermediate
333 storage of "ARRAY" references and final flattening operation used to
334 implement this behaviour, this function is slightly less efficient than
335 "fmap_scalar" or "fmap_void" in cases where item futures are expected
336 only ever to return one, or zero values, respectively.
337
338 This function is also available under the name of simply "fmap" to
339 emphasise its similarity to perl's "map" keyword.
340
341 fmap_scalar
342 $future = fmap_scalar { CODE } ...
343
344 Since version 0.14.
345
346 This version of "fmap" acts more like the "map" functions found in
347 Scheme or Haskell; it expects that each item future returns only one
348 value, and the overall result will be a list containing these, in order
349 of the original input items. If an item future returns more than one
350 value the others will be discarded. If it returns no value, then
351 "undef" will be substituted in its place so that the result list
352 remains in correspondence with the input list.
353
354 This function is also available under the shorter name of "fmap1".
355
356 fmap_void
357 $future = fmap_void { CODE } ...
358
359 Since version 0.14.
360
361 This version of "fmap" does not collect any results from its item
362 futures, it simply waits for them all to complete. Its result future
363 will provide no values.
364
365 While not a map in the strictest sense, this variant is still useful as
366 a way to control concurrency of a function call iterating over a list
367 of items, obtaining its results by some other means (such as side-
368 effects on captured variables, or some external system).
369
370 This function is also available under the shorter name of "fmap0".
371
373 Paul Evans <leonerd@leonerd.org.uk>
374
375
376
377perl v5.36.0 2022-07-22 Future::Utils(3)