Pre-RFC: Catching Functions

I think this comment was poorly phrased:

By "like exceptions" I meant in terms of control flow: you early return on err with ? and then return the non-error case. It is my experience that the way I solve the "must use" on Result 90+% of the time is to call ? on it and forward it up to some larger error handling mechanism. This is the same control flow pattern encouraged in other languages.

But we put up this barrier right now where instead of just typing ? and getting on with it, you see the happy path returns are wrapped in Ok and you have to know the whole system up front.

I don't think it would be positive for users to think that there is unwinding involved - admitting my biases, my experience outside of Rust has mostly been Python and Ruby & I never had to think about how their raising of exceptions was actually implemented. When I say "like exceptions" I'm thinking about the design pattern that exceptions embody, not the implementation mechanism.

It's clear that other people very closely associate language like throw & catch with unwinding mechanisms. I wouldn't object at all to finding alternative language to throw and catch. What's much more relevant to me here is the encoding of this design pattern into a first class syntax, and I'd like if we could separate that question about the feature in its essence (which @chriskrycho for example mostly focuses on) from the question of whether or not the language should mirror exception-based languages.

I don't have another metaphor aside from throwing and catching but the components are:

  • Return on the happy path (return).
  • Return on the error path (throw).
  • Early return to open a result (?).
  • Close both return paths into a result (catch).

I'd love to see some alternative metaphors that don't also complect the question with the question of whether the happy path should use return (not saying that challenging the use of return for the happy path is invalid, just trying to flesh out the total space of possibilities).

Turning toward the question @chriskrycho raises, I think this is the quote that most succinctly expresses the idea:

A way in which the "dialectical ratchet" post was not well tuned to this discussion is that it discussed leverage which occurred over a long period of time. You can go months without having to really understand unelided lifetimes. I think the wording of that post, applied to my poor use of the phrase "like exceptions", suggests that I would think users would go months without learning about Result.

I'm imagining a much narrower period of leverage; the intuitive state gets you through your first PR, but pretty quickly you learn about the Result type. You maybe don't know what to do with Result for a couple more weeks, and keep to the safe zone of ?, but you gain this insight that this is all passing through a return value early on.

However, importantly, what I'm trying to achieve is that you can get much further in making edits to functions that return Result without fully comprehending how error-handling works in Rust.

Overall, our experience is that Rust is a beautifully designed system into which all pieces fit harmoniously, but that nothing makes sense until you learn everything, making it very hard to figure out how to begin. The goal of introducing these instances of dialectical sugar is to allow you to get started before you have understood the whole system.

I think many of us have had the experience of realizing how beautifully well all of the pieces of Rust fit together, and things like Result are a big part of that, but I think it is not urgent that these realizations precede productivity. In fact, I think it is urgent that they not precede it, that users can get things done even before they have realized that Rust is as good as we all think it is.


I actually agree with this. After all, something very similar to the proposal I'm making (but fancier) was in the original RFC by @glaebhoerl. My view is that we accepted half of a feature, and this proposal is an attempt to actualize ? into a holistic and complete system.

What I think Steve meant is that your post could be interpreted "Well, we shouldn't have accepted ?, so going further on that path would be a mistake." But we did accept ?, so even if it were a mistake that doesn't seem like a good argument to leave it half finished. And in contrast to any suggestion ? was a mistake, I've found it to be a resounding success both in my own code and with other users.

For example, I know of a major open source project adopting Rust which otherwise would want have a very conservative version restriction but has decided they absolutely must have at least the version with ?.

8 Likes