Raku's `failure`s are a great success
Raku has failures, a type of delayed exceptions. In try blocks or if you use it (e.g. by calling a method on it), it throws an exception. If you store it as a value, it's an undefined value (which will throw an exception if you use it without handling it).
This is a great compromise that works with try/CATCH in most code and also allows for ergonomic small scripts (or one liners). I've been using this for Audio::TagLib's constructor which allows for either idiom:
# full application:
try {
my $taglib = Audio::TagLib.new($path);
CATCH {
when X::Audio::TagLib::InvalidAudioFile {
... # handle a typed exception
}
when SomeOtherError { ... }
}
... # parse this file
}
# small script:
for @paths -> $path {
with Audio::TagLib.new($path) -> $taglib {
# parse this file
} else {
say "skipping $path: $_";
next;
}
}
# or even shorter (for a one-liner):
for @paths -> $path {
my $taglib = Audio::TagLib.new($path) // next;
... # parse each file
}