Skip to content
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

proposal: improved nil checking #33115

Closed
Terottaja opened this issue Jul 15, 2019 · 21 comments

Comments

@Terottaja
Copy link

commented Jul 15, 2019

What version of Go are you using (go version)?

1.10.3 windows/amd64

What operating system and processor architecture are you using (go env)?

win 8.1 amd64

go env Output
C:\Users\Administrator>go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Administrator\go
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\ADMINI~1\AppData\Local\Temp\go-build237241822=/tmp/go-build -gno-record-gcc-switches

Proposal for C Style nil checking

Instead of

if err != nil {
    panic("Error occurred")
}
// or
if r := result; r != nil {
    print("Result: ", r.Text)
}

you could write

if err { // err is a valid interface and not nil
    panic("Error occurred")
}
// and

if  r := result; r {
    print("Result: ", r.Text)
}

i think this would free up a lot of if err != nil clutter kind of how for {} is and also if statements with multiple nil checks and that this would be great with having to write less and being more productive with Go. If anyone has any better ideas i would like to hear them too to hopefully improve Go as the language evolves and this could be even applied to any other type if they can be nil

@Terottaja Terottaja changed the title object nil checking improved nil checking Jul 15, 2019

@agnivade agnivade changed the title improved nil checking proposal: improved nil checking Jul 15, 2019

@gopherbot gopherbot added this to the Proposal milestone Jul 15, 2019

@gopherbot gopherbot added the Proposal label Jul 15, 2019

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

This would make it too easy to accidentally confuse ok bool results with error results. Today, the lack of == nil suffix distinguishes them on the caller side, making it easier to spot bugs like this one:
https://play.golang.org/p/XUfXSi1w8Mf

@Terottaja

This comment has been minimized.

Copy link
Author

commented Jul 15, 2019

This would make it too easy to accidentally confuse ok bool results with error results. Today, the lack of == nil suffix distinguishes them on the caller side, making it easier to spot bugs like this one:
https://play.golang.org/p/XUfXSi1w8Mf

I think this wouldn't be too confusing because most of the time instead of ok bool you do err error i haven't seen ok error to this day and it would simplify the language when if err != nil is a really big occurrence in go

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

@Terottaja, if the caller mistakenly writes x, ok := […] instead of x, err := […], today that is obvious because the if ok check produces a compile-time error. Under your proposal, that would no longer be a compiler-time error, because if ok would be valid even if the variable ok has type error.

@ccbrown

This comment has been minimized.

Copy link

commented Jul 15, 2019

This looks like a duplicate of #21769, which was declined.

@Terottaja

This comment has been minimized.

Copy link
Author

commented Jul 15, 2019

@Terottaja, if the caller mistakenly writes x, ok := […] instead of x, err := […], today that is obvious because the if ok check produces a compile-time error. Under your proposal, that would no longer be a compiler-time error, because if ok would be valid even if the variable ok has type error.

Seems like that definitely could be done, But could be also evaluated because usually people don't write ok error

@mvndaai

This comment has been minimized.

Copy link

commented Jul 18, 2019

Is it really worth losing the explicitness of if err != nil { for if err.

I would rather have the ! operator work on errors like it does in Javascript or Ruby where a !! can mean != nil because ! turns anything into a boolean.

That would make if err != nil become if !!err { . It is hard to understand at first, but it would keep the language explicit.

@DongchengWang

This comment has been minimized.

Copy link

commented Jul 20, 2019

The if statement should accept a bool. It seems like converting err to a bool implicitly.

if !err? {}
if !?err {}

They reduce readability.

@daflame76

This comment has been minimized.

Copy link

commented Jul 23, 2019

I have to agree with @mvndaai that this proposal risks diluting the clarity of the language and making it behave more like ECMAScript (JavaScript). I really don't think it should go in that direction. However, if a special operator like the !! from Ruby were used that would make it clearer. I'm still not completely in favor of that operator though, but it is better than not specifying anything.

@Terottaja

This comment has been minimized.

Copy link
Author

commented Jul 25, 2019

I have to agree with @mvndaai that this proposal risks diluting the clarity of the language and making it behave more like ECMAScript (JavaScript). I really don't think it should go in that direction. However, if a special operator like the !! from Ruby were used that would make it clearer. I'm still not completely in favor of that operator though, but it is better than not specifying anything.

could also use ? since its not being used anywhere else

@daflame76

This comment has been minimized.

Copy link

commented Jul 29, 2019

@Terottaja the ? symbol is a good possibility. It is already used to denote null-safe dereference in C# so it could make sense for a short-hand nil check in Go.

How do you propose the syntax would look? prefix or postfix?

@daflame76

This comment has been minimized.

Copy link

commented Jul 29, 2019

Also, the only other situation that needs to be made clear is how to use the not nil check for a nil check and have it look sane.

Should this support operator inversion and how.

@Terottaja

This comment has been minimized.

Copy link
Author

commented Jul 30, 2019

@Terottaja the ? symbol is a good possibility. It is already used to denote null-safe dereference in C# so it could make sense for a short-hand nil check in Go.

How do you propose the syntax would look? prefix or postfix?
i think both could work, i think personally prefix because ! and soon to keep consistency.

@mibes

This comment has been minimized.

Copy link

commented Jul 31, 2019

If it is readability you are after, you could consider to add a private has() function to your package:

func has(i interface{}) bool {
	return i != nil
}

You can then rewrite your example like:

if has(err) {
	panic("Error occurred")
}
	
// or

if r := result; has(r) {
	print("Result: ", r.Text)
}

Like: https://play.golang.org/p/MSBQbytsi61

Obvious downside is that you have to redeclare the 'has' function in every package where you need it.

@daflame76

This comment has been minimized.

Copy link

commented Jul 31, 2019

The has() function doesn't reduce the code any not that reducing typing was the goal, but clarity it has().

@daflame76

This comment has been minimized.

Copy link

commented Jul 31, 2019

So, first revised proposed syntax:

if ?err {
    panic("Error occurred.")
}

Votes please.

@daflame76

This comment has been minimized.

Copy link

commented Jul 31, 2019

or second revised proposed syntax:

if err? {
    panic("Error occurred.")
}

Votes please.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jul 31, 2019

This seems like a dup of #32845 and #33152.

@Terottaja Terottaja closed this Sep 3, 2019

@Terottaja

This comment has been minimized.

Copy link
Author

commented Sep 3, 2019

This seems like a dup of #32845 and #33152.

Closing

@daflame76

This comment has been minimized.

Copy link

commented Sep 11, 2019

@Terottaja why was #32845 closed, but #33152 kept open which is newer and this one closed. Not sure what is going on. I would reopen #32845 and close the rest.

@daflame76

This comment has been minimized.

Copy link

commented Sep 11, 2019

Or split up #33152 since it contains several issues in one.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Sep 11, 2019

I wouldn't say that #33152 is being kept open as such. I would say that we haven't gotten to it yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.