On 4/27/13 11:36 AM, Lee Braiden wrote:
On 27/04/13 18:51, Patrick Walton wrote:
On 4/27/13 8:49 AM, Lee Braiden wrote:
This would be a relatively ugly approach, to my way of thinking. Why
should a dead stream be returned at all, if the code to create it
failed?  Why should I be able to call write() on something that could
not be created?

Two reasons:

1. If `open` returned a result type, you'd then have to call `.get()`
on it to achieve task failure. A lot of people dislike this approach.

Right, but this is why the (in this instance) exception model would be
better.

2. We have to have the concept of a "dead stream" or a "stream in the
error state" already, because the OS and standard libraries have this
concept. Given that, it seems simpler to just piggyback on that idea
rather than bifurcating the I/O methods into two: ones that return a
result and ones that set the error state on the stream.

No argument there, except that it might be nice to have a higher-level
API than the OS model.

By default that would cause a task failure.

Ah, I see.

Due to the fact that we don't know how many aliases there are to a
given stream, there's no way to force code that "breaks" a stream to
deal with it in such a way that it relinquishes all references to the
stream. (Actually, we could do it with unique types, but that would be
quite a burden -- you couldn't straightforwardly have a `@FileStream`,
for example.)




Only if you override it with a condition would it be possible to
continue after this

For instance, why should a try_read_uint exist, if you can:

    // assign a handler for read failures
    { read(); }
    // remove the handler

AND have that handler code implemented just once, in a library?

What does `read_uint` return if the handler wants to continue?

Right, I was thinking that Rust had a transaction sort of model for
retrying conditions, but it's just if worked else conditionhandler.

What I mean is, what do these functions return?

    fn read_uint() -> uint { ... }
    fn read_int() -> int { ... }
    fn read_i8() -> i8 { ... }
    ...

If the condition handler doesn't fail, the function has to return something. It could return the result of calling the condition, but that would result in a lot of conditions, since the return types are all incompatible.

No.  My point is that we can provide the best of both models --
exceptions AND local conditions, and avoid some of the speed issues.

Ah, I see what you mean. This seems basically equivalent to what we have now, plus catchable failure and some syntax.

In that case I'm personally OK with catchable failure, although not everybody on the core team is. Perhaps we could introduce a form which is like "spawn a task to catch an exception" from a data sharing view (i.e. it takes an ~fn and can't close over any `@` data) but is optimized to just call the closure and trap failure instead of actually spawning a whole new task.

Regarding new syntax, I'm not sure we need it, as we have macros...

Patrick

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to