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: Go 2: remove the "if" keyword and use "err?!" to avoid error handling boilerplate #33067

Closed
yaxinlx opened this issue Jul 11, 2019 · 22 comments
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Milestone

Comments

@yaxinlx
Copy link

yaxinlx commented Jul 11, 2019

This proposal looks ridiculous, but I think it has some good points, so I post it here anyway.

The proposal proposes that the if-block

if boolCondition {
   ...
} else {
  ...
}

should be simplified as

boolCondition? {
   ...
} else {
  ...
}

More generally, condition values can be of any type, instead of boolean types only:

condValue? {
   ...
} else {
   ...
}

which is equivalent to the current if-block as:

if condValue != zeroValueOfTypeOfCondValue {
   ...
} else {
  ...
}

In other words, the if keyword becomes useless and condValue is equvalent to condValue != zeroValueOfTypeOfCondValue. This really makes the proposal look ridiculous, but I think, currently in Go 1, the if-block and switch-case-block have too much functionality overlapping. In other words, I think the if keyword is not very essential for Go. This is one reason of removing the if keyword.

The other reason of removing the if keyword is we can use the following line

err? !

to simplify

err ? {
   return x, y, err
}

to avoid error handling boilerplate.


[update 1] To avoid breaking the current semicolon insertion rules, err? ! can be replaced with

err?;

or

err??

[update 2] Per Russ's comment, condValue is equvalent to condValue != zeroValueOfTypeOfCondValue can be limited to boolean and error values only, or just excludes string values.

@ianlancetaylor ianlancetaylor changed the title propsoal: Go 2: remove the "if" keyword and use "err?!" to avoid error handling boilerplate proposal: Go 2: remove the "if" keyword and use "err?!" to avoid error handling boilerplate Jul 11, 2019
@gopherbot gopherbot added this to the Proposal milestone Jul 11, 2019
@ianlancetaylor ianlancetaylor added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Jul 11, 2019
@ianlancetaylor
Copy link
Member

We can't realistically remove the if keyword at this point. It would break too many existing Go programs and too much existing Go documentation.

@yaxinlx
Copy link
Author

yaxinlx commented Jul 11, 2019

Cloud you show an example?

@yaxinlx
Copy link
Author

yaxinlx commented Jul 11, 2019

I mean an example which is hard to be fixed by go fix.

@cherrymui
Copy link
Member

If we replace the if keyword with the ? syntax, we'd also replace the else keyword with :.

@Aoang
Copy link

Aoang commented Jul 12, 2019

Excessive simplicity may be a burden.

@dfang
Copy link

dfang commented Jul 12, 2019

this is like ruby's meta programming feature

I agree on this:

Excessive simplicity may be a burden.

@ianlancetaylor
Copy link
Member

Running go fix won't fix the documentation.

@rocket049
Copy link

I oppose.

@yaxinlx
Copy link
Author

yaxinlx commented Jul 12, 2019

@ianlancetaylor, how about keeping the if keyword, but making it optional? and also allow the new way?

About the documentation problem, the change on map printing in Go 1.12 also has the same issue.

@ianlancetaylor
Copy link
Member

Sure, we could just allow the new suggested approach. I was only pointing out that we can't realistically remove the if keyword. That's just not going to happen.

The change to map printing affected fewer people than removing a key element of the language like if, by several orders of magnitude. And the change did not invalidate any existing code, it just changed it to always use a specific order where before it used an unpredictable order. It's really not the same kind of thing at all.

@ianlancetaylor
Copy link
Member

@rocket049 Thanks for the note. I encourage you to either explain your position, or just use the emojis on the first comment to express your opinion. Please see https://golang.org/wiki/NoPlusOne , although in this case I guess it's really NoMinusOne. Thanks.

@ianlancetaylor
Copy link
Member

Note that if

x? {
    ...
}

is equivalent to

if x != zero-value-of-x {
    ...
}

then values of type error and values of type bool will behave somewhat differently. For a value of type error the block will be executed if there is an error. For values of type bool the block will be executed if the value is true. That is, with the typical meanings of those values, in one case we will execute the block if there is a problem, and in the other case we will execute the block if things are OK. This could be acceptable, but it's worth considering.

@mvndaai
Copy link

mvndaai commented Jul 18, 2019

This is very interesting. I like the idea of having one way to know if any type is a zero value or nil.

I would probably prefer a built-in function called isZero() that could work on any type. It does not improve error boilerplate but simplifies other if statements and remove functions like time.Time{}.IsZero().

@ianlancetaylor
Copy link
Member

In the upcoming 1.13 release we do have reflect.Value.IsZero (https://tip.golang.org/pkg/reflect/#Value.IsZero). Definitely more awkward to use than a builtin function.

@mvndaai
Copy link

mvndaai commented Jul 18, 2019

@ianlancetaylor reflect.IsZero sounds helpful. I would probably use it more if it wasn't inside the reflect package. I try to follow The Laws of Reflection which says

It's a powerful tool that should be used with care and avoided unless strictly necessary.

@donaldnevermore
Copy link

donaldnevermore commented Jul 20, 2019

if statement must follow by a bool.

The err?, err?? or err?! breaks the convention of if statement.

@diamondburned
Copy link

I'll be honest, I'd rather have ternary.

@vsg24

This comment has been minimized.

@ianlancetaylor

This comment has been minimized.

@niondir
Copy link

niondir commented Aug 8, 2019

I would already be happy with making either nil falsy everywhere oder just for the error type.

if err { return err}

This would already remove most of the error checking boilerplate and is very simple and straight forward.
Go format can in addition force it to be in one line.

Even this would be simpler to write but not harder to read:

if err := Foo(); err { return err}

@ianlancetaylor
Copy link
Member

This proposal does not add anything to the language we cannot already do. And it's not all that much shorter. And it's potentially confusing. And it has very little support. Therefore, this is a likely decline. Leaving open for four weeks for final comments.

@ianlancetaylor
Copy link
Member

There were no further comments.

@bradfitz bradfitz added the error-handling Language & library change proposals that are about error handling. label Oct 29, 2019
@golang golang locked and limited conversation to collaborators Oct 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
error-handling Language & library change proposals that are about error handling. 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