Pre-RFC: Throwing Functions

@est31 Thanks for substantiating the feeling I’ve had that something’s fishy with the "just coerce to Ok" approach, but couldn’t articulate :slight_smile:

I think the idea to use ? instead of throws in the signature would make sense if we left off the "Try type" in the same way as the throws proposal does. Because in that case, given fn blah()? -> i32 { 42 }, the intuition would be that the type of blah()? as an expression is precisely i32, which is kinda neat. But it unfortunately doesn’t seem like it can work, because it doesn’t leave anywhere to specify what the error type is.

Other things:

  • Someone suggested that a drawback of throws is that it would only work with Result and not other Try types, but I don’t think this has to be the case. In principle, the body of a throws function would never mention the variants of the Try type it’s returning, they would only be created through ? for errors and wrapping for ‘successes’. So in theory it could return any Try type we choose; but even if it returns Result specifically, Try itself allows it to be converted to a different one. If I’m not missing something, then fn foo() -> X throws Y could desugar into any of fn foo() -> Result<X, Y>, fn foo() -> impl Try<Ok=X, Err=Y> (in which case the only thing the caller could do with it is ? or .try()), or fn foo<Res: Try<Ok=X, Err=Y>() -> Res (in which case foo() would desugar to use Try::from_ok() and Try::from_err() at its exit points to convert to whichever type the caller requests), and they all seem like workable approaches (though I haven’t worked it out in detail). I’m not sure which one might be best.

  • This is of course related to how catch should work. I’m of the opinion that catch should just always Ok-wrap (or Some-wrap, etc.) its result, as in the original RFC, but I haven’t had time to read the GitHub thread about this.

  • This also seems related to the design work around async/await, where #[async] would implicitly wrap a function’s written return type in a Future in a similar way to how throws would wrap it in a Result or Try.

3 Likes