Sometimes I wish we could use Thunk as a type:
sub infix:<rescue>(Thunk:D $block, $otherwise) { }
which would then allow you to do:
my $sixdivzero = divide(6,0) rescue -1; # note absence of curlies
One can wish, can’t one?
Liz
> On 3 Aug 2018, at 22:18, Patrick R. Michaud <[email protected]> wrote:
>
> Maybe something like...?
>
> $ cat t.p6
>
> sub infix:<rescue>(Callable $block, $otherwise) {
> CATCH { return $otherwise; }
> $block();
> }
>
> sub divide($a, $b) { die "Zero denominator" if $b == 0; $a / $b }
>
> my $sixdivzero = { divide(6,0) } rescue -1;
> say "6/0 = ", $sixdivzero;
>
> my $sixdivtwo = { divide(6,2) } rescue -1;
> say "6/2 = ", $sixdivtwo;
>
>
> $ perl6 t.p6
> 6/0 = -1
> 6/2 = 3
>
>
> Or if you prefer a prefix form, just declare "rescue" as a normal sub and
> then do:
>
> rescue { divide(6,2) }, -1;
>
> Pm
>
> On Fri, Aug 03, 2018 at 08:34:44PM +0100, Simon Proctor wrote:
>> Hi Sean. I hope my second answer in stackoverflow gets closer to what you
>> want.
>>
>> I am still trying to think of a more idiomatic way of handling to situation.
>>
>>
>>
>> On Fri, 3 Aug 2018, 19:29 Sean McAfee, <[email protected]> wrote:
>>
>>> I posted about this subject on Stack Overflow yesterday[1], but I chose a
>>> poor example of something that raises an exception (dividing by zero, which
>>> apparently doesn't necessarily do so) on which the answers have mostly
>>> focused.
>>>
>>> I was looking for a way to evaluate an expression, and if the expression
>>> threw an exception, for a default value to be provided instead. For
>>> example, in Ruby:
>>>
>>> quotient = begin; a / b; rescue; -1; end
>>>
>>> Or in Lisp:
>>>
>>> (setq quotient (condition-case nil (/ a b) (error -1)))
>>>
>>> Not having written much exception-related code in Perl 6, I hoped that
>>> this might work:
>>>
>>> sub divide($a, $b) { die "Zero denominator" if $b == 0; $a / $b }
>>> my $quotient = do { divide($a, $b); CATCH { default { -1 } } };
>>>
>>> It doesn't, though. As far as I can tell, the value to which a CATCH
>>> block evaluates is ignored; the only useful things one can do in such a
>>> block are things with side effects. Long story short, I eventually came up
>>> with this:
>>>
>>> my $quotient = do { my $q; { $q = divide($a, $b); CATCH { default { $q
>>> = -1 } } }; $q };
>>>
>>> That's far more verbose than I've come to expect from Perl 6. Is there
>>> some more concise way of expressing this logic?
>>>
>>> The doc page on exceptions mentions try, eg:
>>>
>>> my $quotient = try { divide($a, $b) } // -1;
>>>
>>> That works in this specific case, but it seems insufficient in general.
>>> The function might validly return an undefined value, and this construction
>>> can't distinguish between that and an exception. Also, it wouldn't let me
>>> distinguish among various exception cases. I'd have to do something like:
>>>
>>> class EA is Exception { }
>>> class EB is Exception { }
>>> sub divide($a, $b) { (EA, EB).pick.new.throw if $b == 0; $a / $b }
>>>
>>> my $quotient = do { my $q; { $q = divide($a, $b); CATCH { when EA { $q
>>> = -1 }; when EB { $q = -2 } } }; $q };
>>>
>>>
>>> [1]
>>> https://stackoverflow.com/questions/51644197/returning-values-from-exception-handlers-in-perl-6/51670573
>>>
>> --
>> Simon Proctor
>> Cognoscite aliquid novum cotidie