[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] Operator ?! for conditional on exceptions
From: |
Mohammad-Reza Nabipoor |
Subject: |
Re: [RFC] Operator ?! for conditional on exceptions |
Date: |
Sun, 26 Dec 2021 15:05:33 +0330 |
Hi, Jose.
On Fri, Dec 24, 2021 at 06:44:06PM +0100, Jose E. Marchesi wrote:
>
> Hi people!
>
> I have written an implementation of an "excond" operator ?!, that can be
> found in the branch jemarch/excond in poke.git.
>
> This operator has two forms:
>
> EXPRESSION ?! EXCEPTION
>
> and
>
> COMP_STMT ?! EXCEPTION
>
> i.e. as the first operator it can get an arbitrary expression or a
> compound statement.
>
> In both cases, the ?! operator always evaluates to a boolean value. If
> the execution of the expression or statement raises EXCEPTION, the
> result of the operation is 0 (false). Otherwise it is 1 (true). The
> value to which EXPRESSION evaluates is discarded.
>
> Simple example:
>
> if (1/zero ?! E_div_by_zero)
> print "division by zero\n";
>
> A motivation for this feature is, given an union, an easy way to
> determine whether a given alternative is the chosen one without having
> to resort to a clumsy try-catch:
>
> union
> {
> int alt1 : ... ;
> int alt2;
>
> method _print =
> {
> if (alt1 ?! E_elem)
> pretty_print_alt1;
> else
> pretty_print_alt2;
> }
> }
>
> An example with a statement:
>
> if ({ do_whatever_io_operation; } ?! E_eof)
> printf "EOF happened\n";
>
> Using the operator in a statement-expression is also useful. Consider
> this idiom we use in pkl-rt-1.pk and other places:
>
> /* Add the directories in POKE_LOAD_PATH, if defined. */
> try load_path = getenv ("POKE_LOAD_PATH") + ":" + load_path;
> catch if E_inval { }
>
> This can now be rewritten as:
>
> /* Add the directories in POKE_LOAD_PATH, if defined. */
> { load_path = getenv ("POKE_LOAD_PATH") + ":" + load_path } ?! E_inval
>
> What do you people think? Should we put this support in master? Is the
> syntax ok?
>
>
I like it.
The COMP_STMT version is a little bit unusal, but it's useful. Because
otherwise one should write something like this:
```poke
if (lambda int: { do_whatever_io_operation; return 0; } ?! E_eof)
print "EOF happend\n";
```
Interestingly enough, Poke accepts this, too (note the `void`):
```poke
if (lambda void: { do_whatever_io_operation; } ?! E_eof)
print "EOF happend\n";
```
What about supporting more exception codes?
```poke
var not_ok = do_something ?! [E_inval, E_eof];
```