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.