1Future::Utils(3)      User Contributed Perl Documentation     Future::Utils(3)
2
3
4

NAME

6       "Future::Utils" - utility functions for working with "Future" objects
7

SYNOPSIS

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

INVOKING A BLOCK OF CODE

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

REPEATING A BLOCK OF CODE

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

APPLYING A FUNCTION TO A LIST

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

AUTHOR

373       Paul Evans <leonerd@leonerd.org.uk>
374
375
376
377perl v5.36.0                      2022-07-22                  Future::Utils(3)
Impressum