Skip to content

Instantly share code, notes, and snippets.

@fedir
Last active September 13, 2018 15:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fedir/50158bc351b43378b829948290102470 to your computer and use it in GitHub Desktop.
Save fedir/50158bc351b43378b829948290102470 to your computer and use it in GitHub Desktop.
Go 2 error handling with exclamation mark proposal for https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback#other

This is a response for Go 2 error handling proposal.

Proposed in drafts check/handle error handling method adds more complexity, than comfort for developers and make application less maintainable.

The most annoying problem of the current error handling way in Go is the construct if err != nil {, this check is the most popular and developers should repeat it again and again.

So we propose to optimize exactly this pattern, only error handling condition part by reusing ! operator, which could be used as a prefix in conditions, and will be used to check if a variable is not equal to nil.

Here's an example:

Instead of:

a, err = somefunc()
if err != nil {
	// do something
}

Use:

a, err = somefunc()
if !err {
	// do something
}

Conditional logic pattern return err, is not so popular, as draft's authors suppose. So we propose not to optimize it. Here's an example of statistics on real projects, which proves it.

$ find go/src/github.com/ -type f|xargs pcregrep -Ms --buffer-size 1048576 'if err \!= nil {\n.*(\t)'|wc
 206408 1133371 17978161

$ find go/src/github.com/ -type f|xargs pcregrep -Ms --buffer-size 1048576 'if err \!= nil {\n.*(\t)return err'|wc
  13422   55138  801746

Only around 5% of conditions in real projects directly returns errors. You could make such check on Your own project libraries to check it.

The proposed method of error handling has the following advantages over the existing proposal draft:

  • It doesn't require any new keywords.
  • It uses classic Go error handling, and simply optimizes the syntax, it's easy to adopt.
  • It keeps the logic concentrated, so the developer don't need to jump through files to find the good handler.
  • Developers could use traditional error handling with if err {condition} for own logic as usual.
@networkimprov
Copy link

The draft design documents do say they analyzed a large codebase for return err vs other handling code and found that return was the most common. However that's not the case in my projects, so I tend to agree with you.

@ubombi
Copy link

ubombi commented Sep 13, 2018

golang/go#21769 (comment)

This goes against two of Go's strong points.

no implicit type conversions. if checks booleans, and nil isn't implicitly converted to a bool. You could argue that this could be made syntactic sugar instead, saying that if can operate both on booleans, and nilable values. But that raises more concerns: should bool(nilable) be valid code? Should for receive the same capability?

Aside from error checking, nil isn't a very common value in Go. Functions that return nil on failure also return an error or a boolean. In rarer scenarios, where nil is a common value, it usually doesn't require special treatment.

That's in part why nil pointer dereferences are a lot less common in Go, compared to say Java or Ruby. We don't pass nils around for multiple stack frames to blow up eventually.

Your example focuses on if err != nil, which suggests to me that the real intention is to slightly reduce the amount of typing required for error checking. IMO that is not worth the added complexity and other downsides, and we should focus on other proposals that are trying to improve error handling.

@fedir
Copy link
Author

fedir commented Sep 13, 2018

Aside from error checking, nil isn't a very common value in Go. Functions that return nil on failure also return an error or a boolean. In rarer scenarios, where nil is a common value, it usually doesn't require special treatment.

Yes, but in this current case, nil statistically is very used in error checking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment