Renaming task failure

The fact that we use “failure” (and fail!) to refer to our unwinding mechanism often makes it awkward to talk about other kinds of failure. For example, for a function returning a Result, you cannot talk about the operation “failing” without risking ambiguity. You instead have to say something more cumbersome like “the Err case” or "when the operation produces an Err".

The terminology is especially problematic as we move away from task failure and toward Result, since you need to talk about the success/failure of the latter much more often than the former.

A strawman proposal: since task failure entails unwinding (and is essentially exception handling with limited catch points), call it “throwing”, with macro throw!. Then operations like the current recv_opt could instead be labeled recv_catch.

The main downside of using “throw”, of course, is that it suggests we have full-blown exception handling. I’d love to hear additional ideas.

cc @brson @alexcrichton @nikomatsakis

1 Like

I always love to check synonyms, and it sounds like we should start saying “task faux pas”!

On a more serious note, I’m personally ok with the ambiguity, but I could see us renaming it as well. We could tighten up how we refer to these two notions of failure like we have with immutable/shared reference as well. For example we could say that task failure is the thing you can’t catch whereas failure is just “I couldn’t finish” and generally refers to an error case.

On the other hand, renaming may not be so bad. There would be a lot of documentation to update, but that’s not the end of the world. I like the recv_catch pairing with throw!, but I think that throw! invokes the notion of try/catch too much to use it. You’re also not really catching a throw! with recv_catch, you’re more preventing a throw! (in a sense).

One other option may be to call this a “task abort” with an abort! macro. The term abort brings with it “no, you cannot catch this” and we could refer to something like intrinsics::abort as a “process abort”

1 Like

I like the notion of abort as it emphasizes the criticality of the error. May I offer for consideration crash!? Failures are expected to happen, and are potentially recoverable. I can fail to find a file, or fail to get the head of an empty list. A crash on the other hand, invokes (to me) the notion of "there's nothing you can do at this point, we're dead".

Or perhaps in that same vein, die! or kill!

1 Like

die is familiar from Perl, with similar meaning

1 Like

Abort sounds pretty good. We often use the term abort now to mean "a call to abort(3)", but we can always say “process abort” in that case (and, i’ve noticed, we often qualify that with “abort, as in, kill the process”). I tend to agree that saying “we don’t have exceptions” (but we do “throw!”) is likely to get us in trouble, even if it’s true, because it will be confusing. Having exceptions (or, at least, unwinding) by another name seems to be a reasonable and effective way of emphasing that this is not the normal mode of error handling (see Go’s panic/recover).

2 Likes

Any reason we shouldn’t use unwind! ?

(Is it not sufficiently severe sounding?)

The current implementation of task failure is related to unwinding, but I think we don’t want to tie the concept of a task failure to the exact process of unwinding. I think in the past there may have been ideas of how to move away from unwinding, and it would be nice to keep those options in play (not that I know of them though!)

It sounds like abort is the best bet for a replacement. I’m curious whether others share my concern/frustration about the current terminology? Do we think it’s worth changing this?

1 Like

abort! to replace fail! would pair well with kill! instead of intrinsics::abort. kill! works well because it sounds like it does what it does: kill the process.

I like die! because I am familiar with it from other languages, and it would do exactly what I would expect.

1 Like

Yeah, with the talk of maybe removing/changing unwinding, seems bad to rename it to that.

I do agree that fail has problems right now.

Go uses panic and recover: http://blog.golang.org/defer-panic-and-recover

1 Like

How about my_bad! or epic fail!? J

+1 for abort! as it’s probably the best alternative – unless there’s even a small chance that these unwindings could be “caught” in a future Rust, in which case we’re really talking about exceptions.

I think if we ever add a mechanism for intra-task catchable exceptions, it should be semantically and syntactically distinct from task failure / abort / whatever (even if under the hood, they are both implemented by unwinding).

Another potential name here might be error!, which is what Haskell uses for their equivalent. But this conflicts with the current error! for logging, and might also be confusable with the Err variant of Results.

(Gah, I deleted my previous top-level comment so I could make it a reply to the particular comment I’m responding to instead, and now it’s complaining that the body is too similar…)

Instead of having full-fledged exception handling, I think, a lot of safe and deliberate recovery could be done if you had a kind of cheap-to-set-up task that “lends” its caller’s thread (i.e. not starting a new thread for the task).


Another really stupid/ingenious idea I’ve had is parameterised recovery points, akin to lifetimes for parameters.

I am also constantly frustrated about the terminology whenever I write about error handling in Rust. My suspicion is that this pain will be amplified over time.

I like abort!. It tells you exactly what’s going to happen, whereas fail! simply sounds like something has gone wrong.

abort! Looks nice, +1!

Wouldn’t we be talking about task abortion if abort is chosen? I think I prefer crash.

I don’t particularly like “crash” because I think it carries a connotation of uncontrolled execution. I’d like to think of this kind of unwinding as safe and planned.

abort has a nice semantic meaning - it doesn’t sound unsafe like crash or die but it does sound like something you probably shouldn’t do unless you have no other outlet.

It just makes sense in many cases - what do I do if that thing I expected to be x and it inexplicably isn’t? abort the operation.