The existing syntax looks nice to show a newcomer. However, its not a
generally useful API. Any program that cares about error handling can't use
it. If someone shows that code snippet to a newcomer, what newcomer is
looking at is an example of what robust Rust code shouldn't do. Somewhat
like demonstrating C using the gets function. We can put a warning in the
documentation, but many people don't read documentation unless they have a
specific question. If this is used as an example of how to write Rust code,
many people won't make it to the documentation for this method since when
they look up how to iterate over the lines of a file, this example will
come up and they will have no reason to consult the API docs.

If the Rust error handling model is too difficult to show newcomers, then
maybe there is something that needs to be improved in the model. I don't
think having a method that opts out of error handling serves newcomers and
it creates a trap that will be easy to fall into for even non-newcomers.

If there is no point in changing Lines to return IoResult<~str>, I'd be in
favor of #5.

-Palmer Cox



On Wed, Feb 19, 2014 at 5:50 PM, Kevin Ballard <ke...@sb.org> wrote:

> On Feb 19, 2014, at 2:34 PM, Lee Braiden <leebr...@gmail.com> wrote:
>
> Then we could introduce a new struct to wrap any Reader that translates
> non-EOF errors into EOF specifically to let you say "I really don't care
> about failure".
>
>
> It sounds like a very specific way to handle a very general problem.
> People like (modern, complete) scripting languages because they handle this
> sort of intricacy in elegant, ways, not because they gloss over it and make
> half-baked programs that don't handle errors.  It's just that you can, say,
> handle IOErrors in one step, at the top of your script, except for one
> particular issue that you know how to recover from, six levels into the
> call stack.  Exceptions (so long as there isn't a lot of boilerplate around
> them) let you do that, easily.  Rust needs a similarly generic approach to
> propagating errors and handling them five levels up, whether that's
> exceptions or fails (I don't think they currently are flexible enough), or
> monads, or something else.
>
>
> In my experience, exceptions are actually a very *inelegant* way to
> handle this problem. The code 5 levels higher that catches the exception
> doesn't have enough information about the problem in order to recover.
> Maybe it just discards the entire computation, or perhaps restarts it. But
> it can't recover and continue.
>
> We already tried conditions for this, which do let you recover and
> continue, except that turned out to be a dismal failure. Code that didn't
> touch conditions were basically just hoping nothing went wrong, and would
> fail!() if it did. Code that did try to handle errors was very verbose
> because conditions were a PITA to work with.
>
> As for what we're talking about here. lines() is fairly unique right now
> in its discarding of errors. I can't think of another example offhand that
> will discard errors. As I said before, I believe that .lines() exists to
> facilitate I/O handling in a fashion similar to scripting languages,
> primarily because one of the basic things people try to do with new
> languages is read from stdin and handle the input, and it's great if we can
> say our solution to that is:
>
> fn main() {
>     for line in io::stdin().lines() {
>         print!("received: {}", line);
>     }
> }
>
> It's a lot more confusing and off-putting if our example looks like
>
> fn main() {
>     for line in io::stdin().lines() {
>         match line {
>             Ok(line) => print!("received: {}", line),
>             Err(e) => {
>                 println!("error: {}", e);
>                 break;
>         }
>     }
> }
>
> or alternatively
>
> fn main() {
>     for line in io::stdin().lines() {
>         let line = line.unwrap(); // new user says "what is .unwrap()?"
> and is still not handling errors here
>         print!("received: {}", line);
>     }
> }
>
> Note that we can't even use try!() (née if_ok!()) here because main()
> doesn't return an IoResult.
>
> The other thing to consider is that StrSlice also exposes a .lines()
> method and it may be confusing to have two .lines() methods that yield
> different types.
>
> Given that, the only reasonable solutions appear to be:
>
> 1. Keep the current behavior. .lines() already documents its behavior;
> anyone who cares about errors should use .read_line() in a loop
>
> 2. Change .lines() to fail!() on a non-EOF error. Introduce a new wrapper
> type IgnoreErrReader (name suggestions welcome!) that translates all errors
> into EOF. Now the original sample code will fail!() on a non-EOF error, and
> there's a defined way of turning it back into the version that ignores
> errors for people who legitimately want that. This could be exposed as a
> default method on Reader called .ignoring_errors() that consumes self and
> returns the new wrapper.
>
> 3. Keep .lines() as-is and add the wrapper struct that fail!()s on errors.
> This doesn't make a lot of sense to me because the struct would only ever
> be used with .lines(), and therefore this seems worse than:
>
> 4. Change .lines() to fail!() on errors and add a new method
> .lines_ignoring_errs() that behaves the way .lines() does today. That's
> kind of verbose though, and is a specialized form of suggestion #2 (and
> therefore less useful).
>
> 5. Remove .lines() entirely and live with the uglier way of reading stdin
> that will put off new users.
>
> 6. Add some way to retrieve the ignored error after the fact. This would
> require uglifying the Buffer trait to have .err() and .set_err() methods,
> as well as expanding all the implementors to provide a field to store that
> information.
>
> I'm in favor of solutions #1 or #2.
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to