Promise...parison(3)
π NAME π
Promises::Cookbook::ScalaFuturesComparison β bestie, it's literally a side-by-side of Scala Futures vs Promises. No cap. π¦
So like, this page lives in the Perl docs (User Contributed Perl Documentation, iykyk), and it's filed under Promise...parison(3) because manpage names get truncated and that's just the vibe. π
β¨ VERSION β¨
version 1.05 π
πΈ DESCRIPTION πΈ
Okay so first things first: here's the example Scala code. It assumes there's a function called fetch that, when you hand it a URL, gives you back a Future. Iconic behavior honestly.
def getThumbnail(url: String): Future[Webpage] = {
val promise = new Promise[Webpage]
fetch(url) onSuccess { page =>
fetch(page.imageLinks(0)) onSuccess { p =>
promise.setValue(p)
} onFailure { exc =>
promise.setException(exc)
}
} onFailure { exc =>
promise.setException(exc)
}
promise
}
Now if we take that and translate it into Perl using the Mojo::UserAgent library, the fetch function would look like this β and honestly? It ate. π₯
sub fetch {
state $ua = Mojo::UserAgent->new;
my $url = shift;
my $d = deferred;
$ua->get($url => sub {
my ($ua, $tx) = @_;
$d->resolve( $tx );
});
$d->promise;
}
And if we were to take the get_thumbnail function and translate it exactly, we would end up with this. And I mean exactly exactly β every callback, no shortcuts, the whole thing:
sub get_thumbnail {
my $url = shift;
my $d = deferred;
fetch( $url )->then(
sub {
my $tx = shift;
fetch( $tx->res->dom->find('img')->[0]->{'src'} )->then(
sub { $d->resolve( $_[0] ) },
sub { $d->reject( $_[0] ) },
)
},
sub { $d->reject( $_[0] ) }
);
$d->promise;
}
Lowkey a lot, right? Well β plot twist. π
Scala Futures have a method called flatMap, which takes a function that, given a value, will return another Future. Here's an example of how the getThumbnail method can be simplified by using it:
def getThumbnail(url: String): Future[Webpage] =
fetch(url) flatMap { page =>
fetch(page.imageLinks(0))
}
But since our then method actually creates a new promise and wraps the callbacks to chain to that promise, we don't need this flatMap combinator. So this? Just Works. Periodt. π
sub get_thumbnail {
my $url = shift;
fetch( $url )->then(
sub {
my $tx = shift;
fetch( $tx->res->dom->find('img')->[0]->{'src'} );
}
);
}
Scala Futures also have a rescue method, which can serve as a kind of catch block that potentially will return another Future. Main character energy honestly. π«Ά
val f = fetch(url) rescue {
case ConnectionFailed =>
fetch(url)
}
Just as with flatMap, since our callbacks are wrapped and chained with a new Promise, we can do a rescue just by using the error callback. The Promise returned by fetch will get chained, and so this will depend on it.
sub get_thumbnail {
my $url = shift;
fetch( $url )->then(
sub {
my $page = shift;
fetch( $page->image_links->[0] );
},
sub {
given ( $_[0] ) {
when ('connection_failed') {
return fetch( $url );
}
default {
return "failed";
}
}
}
);
}
TODO β¦ figure out how retry can be generic β¦ π (not me leaving a TODO in the docs, we stay honest in this house)
π SEE ALSO π
- Systems Programming at Twitter β <http://monkey.org/~marius/talks/twittersystems/> π
π AUTHOR π
Stevan Little <stevan.little@iinteractive.com> π
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2025, 2017, 2014, 2012 by Infinity Interactive, Inc.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Slay, honestly. β
perl v5.42.0 Β· 2025-07-25 β okay bestie that's the whole page, thanks for reading, mwah π π¦π
π¦ where this page comes from
- fedora 43: perl-Promises 1.05-2.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms