The Past, The Present and The Future
Paul Evans (PEVANS, LeoNerd)�$LOCATION
The Past
Straight line code
Synchronous
The Past
sub get_ball {
my ( $c ) = @_;
my $ball = slowly_get_ball($c);
return $ball;�}
my $red_ball = get_ball( "red" );
say $red_ball;
Asynchronous Callbacks
Pass in CODE reference
Function keeps it to call it later
Control flow goes backwards
Asynchronous Callbacks
sub get_ball_a {
my ( $c, $on_ball ) = @_;
...
}
my $on_ball = sub { say $_[0] };
get_ball_a( "red", $on_ball );
Futures
A proxy value
Represents an ongoing operation
Futures
sub get_ball_f {
my ( $c ) = @_;
return ## magic goes here ##�}
my $f = get_ball_f( "red" );
say $f->get;
cpan> Future
sub get_ball_f {
my ( $c ) = @_;
my $f = Future->new;
$f->done( Ball->new( $c ) );
return $f
}
cpan> Future
sub get_ball_f {
my ( $c ) = @_;
my $f = Future->new;
BallFetcher->fetch( $c,
sub { $f->done( @_ ) });
return $f
}
cpan> Future
my $f = get_ball_f( "red" );
$f->on_done(
sub {
my $ball = shift;
say $ball;
}
);
cpan> Future
Subclass or Proxy for more control
my $f = get_ball_f( "red" );
$f->await; ## implicit
my $ball = $f->get;
say $ball;
Success or Failure
Operations can succeed or fail
Futures can yield results or exceptions
Success or Failure
my $f = get_ball_f( "yellow" );
if( not $f->failure ) {
my $ball = $f->get;
}
else {
...
};
Success or Failure
my $f = get_ball_f( "yellow" );
try {
my $ball = $f->get;
}
catch {
...
};
Combining in Parallel
Want to do things concurrently
Combine many Futures to await them all
Combining in Parallel
my $f = Future->needs_all(
get_ball_f( "red" ),
get_ball_f( "green" ),
get_ball_f( "blue" )
);
my ($red, $green, $blue) = $f->get;
Combining in Sequence
A Future can trigger more code
... which can return another Future
Success or Failure
my $ball;
try {
$ball = get_ball_f( "yellow" )
->get; }
catch {
$ball = get_ball_f( "orange" )
->get; };
say $ball;
Success or Failure - better
my $f = get_ball_f( "yellow" );
my $g = $f->or_else( sub {
get_ball_f( "orange" )
});
say $g->get;
Success or Failure - better
my $f = get_ball_f( "yellow" )
->or_else( sub {
get_ball_f( "orange" )
});
say $f->get;
Cancelling
A Future is an operation in-progress
Operations can be cancelled
Cancelling
my $f = get_ball_f( "purple" );
sleep 20;
$f->is_ready or $f->cancel;
Cancelling Example: Timeouts
my $f = Future->wait_any(
get_ball_f( "purple" ),
timeout_f( 20 )
);
my $ball = $f->get;
Resources
cpan> install Future
LeoNerd @ irc.freenode.net, irc.perl.net
PEVANS on CPAN�