Of course, the particular symbol is up for debate. I also considered _^, _*, @, and others. I chose _! as the de-facto suggestion because I thought it would be the most familiar at a glance.
Syntactically, _! (or the chosen token) would be a symbol of type error available in the scope in which it is used. It starts out as nil, and any time it is assigned to, a nil check is performed. If it is set to a non-nil error value, a panic is started. Because _! (or, again, the token chosen) would not a syntactically valid identifier in go, name collision wouldn't be a concern. This ethereal variable would only be introduced in scopes where it is used, similar to named return values. If a syntactically valid identifier is needed, perhaps a placeholder could be used that would be re-written to a unique name at compile time.
One of the more common criticisms I see leveled at go is the verbosity of error handling. Errors at API boundaries aren't a bad thing. Having to get the errors to the API boundaries can be a pain though, especially for deeply recursive algorithms. To get around the added verbosity error propagation introduces to recursive code, panics can be used. I feel that this is a pretty commonly used technique. I've used it in my own code, and I've seen it used in the wild, including in go's parser. Sometimes, you've done validation elsewhere in your program and are expecting an error to be nil. If a non-nil error were to be received, this would violate your invariant. When an invariant is violated, it's acceptable to panic. In complex initialization code, sometimes it makes sense to turn errors into panics and recover them to be returned somewhere with more knowledge of the context. In all of these scenarios, there's an opportunity to reduce error boilerplate.
I realize that it is go's philosophy to avoid panics as much as possible. They are not a tool for error propagation across API boundaries. However, they are a feature of the language and have legitimate use cases, such as those described above. Panics are a fantastic way to simplify error propagation in private code, and a simplification of the syntax would go a long way to make code cleaner and, arguably, clearer. I feel that it is easier to recognize _! (or @, or `_^, etc...) at a glance than the "if-error-panic" form. A token can dramatically decrease the amount of code that must be written/read to convey/understand:
there could be an error
if there is an error, we're not expecting it
if there is an error, it's probably being handled up the chain
As with any syntax feature, there's the potential for abuse. In this case, the go community already has a set of best practices for dealing with panics. Since this syntax addition is syntactic sugar for panic, that set of best practices can be applied to its use.
In addition to simplification of the acceptable use cases for panic, this also makes fast prototyping in go easier. If I have an idea I want to jot down in code, and just want errors to crash the program while I toy around, I could make use of this syntax addition rather than the "if-error-panic" form. If I can express myself in less lines in the early stages of development allows me to get my ideas into code faster. Once I have a complete idea in code, I go back and refactor my code to return errors at appropriate boundaries. I wouldn't leave free panics in production code, but they can be a powerful development tool.
I am open to any and all feedback from the go team and the community.
The text was updated successfully, but these errors were encountered: