Hacker News new | ask | show | jobs
by deathanatos 4154 days ago
> The issue is it makes it difficult to notice that a function might return when scanning through a function.

What other solutions are there? The only other approach to error handling I've seen is exceptions (e.g., C++, Java, C#, JS…), and if you don't like `try!` because it is a "hidden return", you certainly won't like exceptions. At least with Rust's macros, I know that in the absence of one, there is no return; in the presence, there might be. Exceptions in most languages make no guarantee.

2 comments

It's a trade off. For the trouble of exceptions I get nice benefits like stack traces (though there are proposals to add stack traces to Rusts error handling). There are times when I really like exceptions, and times (such as trying to trace through an execution path) that I'm irritated by them.

What other solutions are there? Well, you could make the return explicit:

    let z = try!(x / y, onerror = return)
There are obvious downsides, such as added verbosity, and the need to figure out keyword arguments in macros, and do you allow access to the error value etc. but at least I can grep for/highlight "return". It also makes the meaning of the slightly confusingly named "try" more obvious (again, I'm vaguely aware of proposals that would change the name).

I think ultimately try! is a good thing, but I don't think it's trivially "a very appropriate use of macros". It's a considered use given some difficult trade-offs.

Kotlin has a notion of function inlining with the return statement being inlined too. This means you can do, e.g.:

list.forEach { if (it == something) return; }

and you aren't returning from the code block, but the enclosing function. Yet behind the scenes forEach is being expanded by the compiler into a regular imperative for loop, in a macro-like way.