Skip to content

Proposal: Support inline "if" statement syntax #32860

@andreynering

Description

@andreynering

This is a brainstorming idea that came from #32825 (comment).

To be honest, I'm not sure if a agree with my own proposal, since it goes against some Go conventions, which disallow one-line-ifs (#27135) or the ternary operator, for example.

Even then, I think it's worth posting the idea here and raise some discussion.


Proposal

I propose that Go could allow inline if statements, just like Ruby does. This means that a code like this:

if value < 0 {
	value = 0
}

Could be written like this:

value = 0 if value < 0

Or, to give a more common example:

if err != nil {
	return errors.Wrap(err, "oops")
}

Could be written as:

return errors.Wrap(err, "oops") if err != nil

Some experiences from Ruby

On the Ruby world, inline if statements are used a lot. Some Rubysts think inline if`s shouldn't be used for non-return statements, though, for a similar reason why Go requires blocks on if statements: it makes it harder to follow code paths.

Based on that, it's also a possibility to only allow inline if on return statements:

// this would work
return foo.thing() if foo != nil

// this would raise a compiler error
foo.doSomething() if foo != nil

This restriction may prevent users to misuse this feature. Requiring a return in the beginning of the line would mitigate the raise on complexity while reading code searching for code paths.

Talking about errors

While this proposal has no relation to errors per se, it's true that the most common use case would be reducing the number of lines of code required to do error handling. In theory, in most cases this would allow 1 line to check + return an error instead of 3.

Pros

I think this proposal is way saner then #32437 which proposes the try built-in:

  • try is black magic, and will be likely very confusing for beginners, while return is clear
  • try is implicit, returns are explicit
  • try disallow doing anything different than just returning the error, while with a plain return ... if people still have control to return a wrapped error or to modify the if statement:
    • return err if err != nil && err != context.Cancelled

I also think this is better than most errors proposals out there (including handle, etc).

Cons

  • Harder to follow code paths, since if blocks are easier find while scanning code
  • Can encourage programmers to write long lines (80+ characters) which reduces readability
  • This breaks with existing Go conventions (but not more than try or handle, IMHO)

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeLanguageChangeSuggested changes to the Go languageProposalerror-handlingLanguage & library change proposals that are about error handling.v2An incompatible library change

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions