You write:

> So what actually happens if `new` encounters an error? To understand
> that it's important to know that what `new` returns is not a `File`
> but an `Option<File>`. If the file does not open, and the condition
> is handled, then `new` will simply return `None`. Because there is an
> implementation of `Writer` (the trait required ultimately required for
> types to implement `write_line`) there is no need to inspect or unwrap
> the `Option<File>` and we simply call `write_line` on it. If `new`
> returned a `None` then the followup call to `write_line` will also
> raise an error.

I'm an outsider, so apologies if I'm off the right track. But this sounds
wrong to me. Isn't the point of condition handlers to /handle the
condition/? Meaning resolve the problem, so that processing can continue?
Here as far as I can tell, they're only being used to say "fail
differently", which then leads to failing again the next time you try to do
something. Opening a file was actually one of the examples used to
illustrate the condition system way back when[1].

> * XXX: How should we use condition handlers that return values?

IMHO the right way would be to provide more fine-grained information about
the error (perhaps raising different conditions depending on the error,
instead of always the same condition and a giant enum describing it), and
use the return value of the condition to set policy wrt how to handle it
and/or to provide a substitute (as in the example). If there's nothing
reasonable that could be done, don't raise a condition, fail
unconditionally.

Whether to respond to failure by failing the task or by indicating it in
the return value seems like it would be better handled by having separate
functions for each. In the case where you expect success, the result
shouldn't be an Option. If the result is an Option, it shouldn't fail the
task (whether or not a condition handler is present). So for example:

open<P: PathLike>(path: &P, mode: FileMode, access: FileAccess) ->
FileStream

try_open<P: PathLike>(path: &P, mode: FileMode, access: FileAccess) ->
Option<FileStream>

If the expect-success version of a function returns (), the try_ version
would return bool rather than Option<()> (which are isomorphic).

Upon encountering an error, open() would raise a condition, and then
continue if possible, otherwise fail!().

I'm not sure whether try_open() would raise a condition or not. The way
conditions were described, if they aren't handled, the task fails.
try_open() definitely shouldn't fail. Would it be reasonable to raise a
condition and instead of failing, return None if it's not handled? If not,
then try_open() shouldn't raise any conditions, and should just return None.

The obvious drawback is twice as many functions, but it feels preferable to
forcing two different behaviours onto the same function. The fast
(expect-success) path would be just as clean as before, if not cleaner.

[1] https://mail.mozilla.org/pipermail/rust-dev/2012-October/002545.html
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to