Live data from Hacker News

On Error Handling in Rust

lucumr.pocoo.org

71–80 of 82 posts

Re: On Error Handling in Rust

#71

Earlier quoted context omitted.

To be fair, a similar argument also applies to structs vs. tuples. Unpacking them is really awkward. I suspect language designers only tolerate them because they're so convenient in practice for representing mathematical tuples (where order is actually semantically significant) and have very lightweight syntax in cases where you want to use all or most of the values. But with variants, order is never meaningful and y…

Order is important in rust variants? That sucks, hmm I hadn't thought about it in this much depth and it's probably obvious from literature seems like there is a whole spectrum of variants then: 1. wrapper variants (where the choosen instance is given a key or it's own wrapper type) 2. ordered variants (where the choosen instance if keyed by it's position) 3. type variants (The only way to differentiate is by type, d…

Order isn't currently significant; it's the RFC (which I haven't seen) which proposed adding this in some form.

Re: On Error Handling in Rust

#72

Earlier quoted context omitted.

Yeah, but that doesn't extend to match { let f = fopen(); fwrite("aha", f); fclose(f); } { Err(e) => println("either of fopen, fwrite or fclose failed"), _ => () } without something like a try! variant that breaks out of a block instead of returning from a function on error.

This is exactly what the Error / Either monad does.

Can't be, it does IO!

Re: On Error Handling in Rust

#73
post #31

In some ways it's heartening to see Rust working everything out for itself - but it's also painful to watch the language stumble on the same problems that we've already solved. You're going to hit the same problem again with async, with transactions, and with resource management; indeed some of the stuff I've already seen about borrowing and the like seems achingly close to the same pattern. Introducing new sigils li…

Yeah, sure, a higher kinded type here, syntax sugar for generalized computation side effects there, and before you know it you're neckdeep in monad transformers and your head rapidly decompresses in a combinatorial explosion every time you try to do a new thing and users need to remember seven different type parameters to read a line from stdin. :(

Re: On Error Handling in Rust

#74
post #46

Earlier quoted context omitted.

Removing the old notation was certainly not solely motivated by wanting to free up the keyword, but the reason that it remains reserved is in anticipation of future use, rather than simple negligence (though of course this decision could be reversed before 1.0).

Right, I guess I meant that it's not just for HKT, but for something useful. Anyway, none of this particularly matters.

F# doesn't have HKT, but still has a variant of do syntax via "computation expressions" http://msdn.microsoft.com/en-us/library/dd233182.aspx. It's less elegant than HKT because you have to name the monad used for the expression i.e. io { exprs }, and also involves additional boilerplate code to define them - but accomplishes many of the same objectives.

Re: On Error Handling in Rust

#75
post #40

Earlier quoted context omitted.

Note my mention of the too-many-small-functions-with-one-caller(tm) smell. It refers to this solution.

It would be inlined by the compiler, and the standard library could introduce a macro to eliminate the awkward code. try!({ let db = pgsql.connect(localhost)? let stmt = db.prepare("INSERT INTO log VALUES(?,?)")? stmt.execute(("debug", "Note to self: debug logs are noncritical"))? } catch err: DatabaseError { println!("Could not write log to database {}", err); }) ===> match (|| { let db = pgsql.connect(localhost)? l…

Closures aren't "free", you need to structure your code around being unable to return/break/continue across the closure boundary, and there's probably some silly borrow checker errors involved too.

Re: On Error Handling in Rust

#76
post #5

So it's a specialized mapping operator for the Result functor. Why restrict it to Result only? What about using option to denote a failure condition without a specific reason? Or other kinds of interesting functors?

Mapping is just the map method. This is about early return, so maybe you could construe it as a specialized whatsit in the Cont monad.

http://doc.rust-lang.org/core/result/enum.Result.html#method... http://doc.rust-lang.org/core/option/enum.Option.html#method...

Re: On Error Handling in Rust

#77
post #71

Earlier quoted context omitted.

Order is important in rust variants? That sucks, hmm I hadn't thought about it in this much depth and it's probably obvious from literature seems like there is a whole spectrum of variants then: 1. wrapper variants (where the choosen instance is given a key or it's own wrapper type) 2. ordered variants (where the choosen instance if keyed by it's position) 3. type variants (The only way to differentiate is by type, d…

Order isn't currently significant; it's the RFC (which I haven't seen) which proposed adding this in some form.

Wow, I just looked over some of them and I think it's awesome that Rust has these RFCs tied to pull requests. Scala has SIPs but they are much less frequently used, and their granularity is much more coarse, yet they are less detailed and commented on by the community.

Re: On Error Handling in Rust

#78
post #74

Earlier quoted context omitted.

Right, I guess I meant that it's not just for HKT, but for something useful. Anyway, none of this particularly matters.

F# doesn't have HKT, but still has a variant of do syntax via "computation expressions" http://msdn.microsoft.com/en-us/library/dd233182.aspx . It's less elegant than HKT because you have to name the monad used for the expression i.e. io { exprs }, and also involves additional boilerplate code to define them - but accomplishes many of the same objectives.

The problem is that without HKT you can't abstract over these things; you can't write useful functions like "sequence", and so code that uses these expressions becomes a kind of second-class citizen that can't be refactored the way you'd do with normal code.

Re: On Error Handling in Rust

#79
post #78
post #74

Earlier quoted context omitted.

F# doesn't have HKT, but still has a variant of do syntax via "computation expressions" http://msdn.microsoft.com/en-us/library/dd233182.aspx . It's less elegant than HKT because you have to name the monad used for the expression i.e. io { exprs }, and also involves additional boilerplate code to define them - but accomplishes many of the same objectives.

The problem is that without HKT you can't abstract over these things; you can't write useful functions like "sequence", and so code that uses these expressions becomes a kind of second-class citizen that can't be refactored the way you'd do with normal code.

Of course, HKT is preferable, just in the error reporting context (i.e. this particular example) I'm not sure much the addt'l abstraction (functions like sequence) further solves the problem, seems like the expressions described may be sufficient.

But I agree, in general, you absolutely want HKT for the reasons you mentioned.

Said another way, if HKT in rust is doable, let's do that - but if that turns out not to be the case, there are some nice conpromises such as this example, which I think, at least, is better than the proposed ? Operator, because it is a bit more general/versatile.

Re: On Error Handling in Rust

#80

This is a sugar-coated version of errors as return values. It fixes the most glaring problem, which is code that does not check for errors, common in C: FILE* f = fopen("somefile", "r"); fwrite("aha", 4, 1, f); // In Rust (pardon my rust, I'm totally ignorant), it'd be: let f = fopen("somefile", "r"); fwrite("aha", f)?; The compiler would know that fopen may return an error, and forbid me from running unchecked code.…

There's an RFC for try/catch: https://github.com/glaebhoerl/rfcs/blob/trait-based-exceptio...
Post reply on HN