So, maybe what's needed is a C<warn> catcher (C<WARNCATCH>... eew),
where C<warn> would throw an exception object with an attached
continuation. And of course, if a warning reached the top of the
stack without being caught, it would print itself and invoke its
continuation.
I thought I'd try and see how this would work. A toy example: implementing saturated arithetic uses exceptions:
sub incr ( int $a is rw is checked )
{
$a++;
CATCH {
when IntegerOverflow { $a = int.max };
default { throw }
}
}This would work for a single variable, but no extend it to do a few more:
{
$a++;
$b++;
$c++; WARNCATCH
{
when IntegerOverflow { .recover = int.max; .resume };
}
}I think it is safe to assume that an exception object that provides a .resume method will also provide methods/attributes to allow a hander to take corrective action before resuming. Hence the .recover attribute would need be a standard feature of all exceptions: it just happens to be the name used by the IntegerOverflow object.
How would this look from the thrower's side? I can think of a few possibilities. I think we currently have C<throw> to throw a terminal exception. C<warn> isn't right, because C<die> isn't C<throw>. So what's a less ballistic approach to a throw? A C<bounce>, C<pong>, C<panic>? I'm not sure of the keyword, but useage could look something like:
sub postfix:++ (int $a is rw)
{
if ($a == int.max)
{
lob IntegerOverflow.new( var=>$a, overshoot=>1 )
}
else
{
$a = $a + 1
}
return $a;
}I think it could work, and the rope's not really enough to hang the unwary.
Dave.
p.s. the example is a toy, but saturated arithmetic is useful, and often supported in the instruction set of the host cpu --- any chance of it being build into parrot/jit? Ditto for overflow exceptions.
