Skip to content

proposal: Go 2: introduce interface type to solve nil comparison dilemma #43269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
marcosrmendezthd opened this issue Dec 18, 2020 · 6 comments
Closed
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Milestone

Comments

@marcosrmendezthd
Copy link

There's a lot of discussion regarding comparing interfaces to nil (https://golang.org/doc/faq#nil_error, #22729). I recently had to deal with this, and as a developer, I'm surprised we haven't had more issues since errors are interfaces. It is not a trivial issue to solve.

My humble suggestion is to introduce another type with new semantics.

We would migrate the error type so that err != nil or err == nil always works. The new type would be interoperable with a regular or typed interfaces. It should essentially work the same except for comparisons, where the new semantics could then be introduced.

type error new_type {
   Error() string
}

Developers could then start migrating their code to use this new type as needed, so that existing code doesn't have to be changed immediately and we don't introduce any breaking changes.

type new_typed_interface new_type {
  ...
}

y := getLegacyTypedInterface().(new_typed_interface)

if y != nil {
...
}

Thoughts? Comments?

@ianlancetaylor
Copy link
Contributor

Can you be more precise? After all, err != nil and err == nil already always works. You have some other definition of "works," and you need to write it down precisely. Thanks.

See also #21538, #24635, #24682, #27890, #30294, #30865

@ianlancetaylor ianlancetaylor changed the title proposal Go2 : introduce interface type to solve nil comparison dilemma proposal: Go 2: introduce interface type to solve nil comparison dilemma Dec 18, 2020
@gopherbot gopherbot added this to the Proposal milestone Dec 18, 2020
@ianlancetaylor ianlancetaylor added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Dec 18, 2020
@marcosrmendezthd
Copy link
Author

@ianlancetaylor well, this works assuming that the error is not pointer to a struct as shown on the faq (https://golang.org/doc/faq#nil_error). however, introducing this new type would also solve for checking interfaces in general.

with the amount of Go code out there, we're leveraging a lot of libraries that we can't validate. we don't know if they're returning a "nil" pointer to struct, either for an error or some other typed interface. since error is an interface, this type of issue can arise.

https://play.golang.org/p/82-VQaCso_4

@ianlancetaylor
Copy link
Contributor

When talking about language semantics at this level of detail, it's essential to be really precise.

err == nil works fine today. The result is an untyped true if err is the zero value of the interface type, or an untyped false if it is not. To expand a bit, an interface is a pair: a type and a value of that type. In the zero value of an interface, the type is nil. It is possible for an interface value to hold a pair of a non-nil type and a zero value of that type. In that case, the interface does not compare equal to nil. But if the type in the interface is a pointer, slice, channel, map, or function type, then it is possible that the value of that type, stored in the interface, is nil, even though, to repeat, the interface does not compare equal to nil.

When you say that it doesn't work if the error is a pointer to a struct, you probably mean something like err != nil is true even though the value stored in the interface is a nil pointer. But I hope that we can all agree that it does work according to the language specification and according to an understanding that an interface is a pair of a type and a value.

If we want different behavior, that behavior has to be specified precisely, just as the current behavior is specified precisely. In order to change the language, you need to provide that precise specification.

@ianlancetaylor
Copy link
Contributor

Based on the discussion above, this is a likely decline. Leaving open for four weeks for final comments.

@marcosrmendezthd
Copy link
Author

ok. sorry was on vacation. will be updating our code to use a func to validate specific interface checks that could be problematic. thanks.

@ianlancetaylor
Copy link
Contributor

No change in consensus.

@golang golang locked and limited conversation to collaborators Feb 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

3 participants