Skip to content

Commit 7136f93

Browse files
committed
Make winner {} about Channel's only
1 parent 5027a94 commit 7136f93

File tree

1 file changed

+40
-47
lines changed

1 file changed

+40
-47
lines changed

S17-concurrency.pod

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -373,45 +373,7 @@ result.
373373
my ($a, $b) = await $p1, $p2;
374374

375375
This simply calls C<result> on each of the C<Promise>s, so any exception will
376-
be thrown. There is also a C<winner> statement [keywords still negotiable]:
377-
378-
winner * {
379-
done $p1 { say "First promise got a value" }
380-
done $p2 { say "Second promise got a value" }
381-
}
382-
383-
That will invoke the closure associated with the first promise that
384-
produces a result, either kept or broken.
385-
386-
It's possible to add a timer using the keyword C<wait> followed
387-
by the number of seconds to wait (which may be fractional). As a
388-
degenerate case, in order to avoid blocking at all you may use a
389-
C<wait 0>. The timeout is always checked last, to guarantee that
390-
the other entries are all tried at least once before timing out.
391-
392-
my $gotone = winner * {
393-
done $p1 { say "First promise got a value"; $p1 }
394-
done $p2 { say "Second promise got a value"; $p2 }
395-
wait 0 { say "Not done yet"; Nil }
396-
}
397-
398-
The construct as a whole returns the result of whichever block was selected.
399-
400-
It's also possible to process a variadic list of promises together,
401-
using generic code that works over some set of the promises (use C<*>
402-
to represent any of them). The index and promise are passed to the
403-
code as named arguments C<$:v> and <$:k> (possibly via priming if
404-
the code is instantiated ahead of time).
405-
406-
winner * {
407-
done @promises { say "Promise $:k was kept, result was: ", $:v.result }
408-
}
409-
410-
In this case C<$:k> returns the index of the promise, base 0.
411-
Likewise C<$:v> returns the promise object itself. Conjecture: the result
412-
should be bound to C<$_> to make it work more like channels below.
413-
414-
[Conjecture: we should allow different cases for success or failure.]
376+
be thrown.
415377

416378
=head1 Channels
417379

@@ -447,9 +409,45 @@ calls to a channel return the same promise, not a new one.
447409
While C<receive> blocks until it can read, C<poll> takes a message from the
448410
channel if one is there or immediately returns C<Nil> if nothing is there.
449411

450-
The C<winner> construct also works on channels, and will try to receive a value
451-
from the first C<Channel> that has one available. It also automatically checks
452-
the C<.done> promise corresponding to the channel, so it can also be used in order
412+
There is also a C<winner> statement [keywords still negotiable]:
413+
414+
winner * {
415+
more $c1 { say "First channel got a value" }
416+
more $c2 { say "Second channel got a value" }
417+
}
418+
419+
That will invoke the closure associated with the first channel that
420+
receives a value.
421+
422+
It's possible to add a timer using the keyword C<wait> followed
423+
by the number of seconds to wait (which may be fractional). As a
424+
degenerate case, in order to avoid blocking at all you may use a
425+
C<wait 0>. The timeout is always checked last, to guarantee that
426+
the other entries are all tried at least once before timing out.
427+
428+
my $gotone = winner * {
429+
more $c1 { say "First channel got a value" }
430+
more $c2 { say "Second channel got a value" }
431+
wait 0 { say "Not done yet"; Nil }
432+
}
433+
434+
The construct as a whole returns the result of whichever block was selected.
435+
436+
It's also possible to process a variadic list of channels together,
437+
using generic code that works over some set of the channels (use C<*>
438+
to represent any of them). The index and the received value are passed to
439+
the code as named arguments C<$:k> and <$:v> (possibly via priming if
440+
the code is instantiated ahead of time).
441+
442+
winner * {
443+
more @channels { say "Channel $:k received, result was: ", $:v }
444+
}
445+
446+
In this case C<$:k> returns the index of the channel, base 0.
447+
Likewise C<$:v> returns the value.
448+
449+
The C<winner> construct also automatically checks the C<.done> promise
450+
corresponding to the channel, so it can also be used in order
453451
to write a loop to receive from a channel until it is closed:
454452

455453
gather loop {
@@ -458,11 +456,6 @@ to write a loop to receive from a channel until it is closed:
458456
done * { last }
459457
}
460458
}
461-
462-
This works because C<more> only ever works on channels, while C<done>
463-
only ever works on promises, so it knows to check the promise of
464-
channel C<$c> rather than C<$c> itself.
465-
466459
This is such a common pattern that we make a channel in list context behave
467460
that way:
468461

0 commit comments

Comments
 (0)