-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: Support inline "if" statement syntax #32860
Comments
if err != nil return err Why would your proposal be better than this example? I don't like either, though. |
Would it also allow single-line See also #32611 which suggests: |
Well, the obvious sequitur seems to me only a little stretch to Go syntax; not beautiful, but that is in the eye of the beholder:
as in - for the case in point:
Which then might just lead to the totally heretical:
and an incompatible idiom for returning the now "special" error argument:
(note that I intentionally omitted the "err" return argument name to suggest that the elements either side of the semicolon may be treated differently), but that is starting to look like an unsightly mess. Also, maybe the return needs parentheses to "escape" the semicolon: or
I leave that to the referees. Well, one needs to turn every stone... |
@henvic I never saw a language that allow that. IMO that's harder to read, since you don't have a keyword to separate the if statement to the rest of the code. Yes, you have if value < 0 value = 0 Having the
@networkimprov I disagree with supporting inline About inline
@lootch This falls in the same problem other proposals do, it more complicates then simplify things. That statement is less readable than a plain if statement, and I'm sure it could be confusing to new Gophers. Inline ifs are just code, as we've already been writing, but inline to save a few lines of code. |
If you really wanted to collapse error checks into a single line, a much smaller change would be for gofmt to allow:
That opens its own list of questions, such as "what about |
@mvdan, ppl keep repeating that, but it's not actually trivial.
And would the new go fmt rewrite much existing error code? |
I'm not saying it's a good idea. I'm saying that introducing new syntax generally has a higher cost. |
Generally. But in this case, probably not. |
I've always been an advocate of go fmt allowing However, I'd leave it at that as doing more would open up a can of worms. In particular, I wouldn't allow it if there was an |
I think that's the point: by having the inline To be honest, I'm fine with our current state, and have upvoted #32825 to reflect that. 🙂 But if we're going to make a change, I think it may be worth paying the cost to have a better and flexible syntax. A lot of other proposals also requires deeper changes, but this one is simpler. |
I think this proposal would make it too easy to bury important side-effects. x = thingThatNeedsToHappenForSideEffect() if false // Easy not to notice the 'if`'. x = y if thingThatModifiesY() // Does x use the value of y from before the mutation, or after? |
@bcmills I agree that code like that shouldn't be written. But I think that while we should in general reduce the possibility of bad code, we can't 100% guarantee that the user won't shoot their own foot. I mean: functions with side effects are almost always bad and should be avoided. The inline if itself don't encourage code like that. |
In my opinion return fmt.Errorf("my error: %v", err) if err != nil is harder to read, because it buries the important part. When skimming through the code, it looks like a I don't understand the benefit that is worth the cost. The "pros" listed above are all about how |
To be honest, this is indeed more a counter-proposal to That said, the only real benefit here is reducing lines of code and boilerplate. (Actually, that's also the only benefit of
Well, I think this would be specially surprising for people that are not aware of this syntax, but perhaps people would get used to it. On the Ruby world, most people doesn't complain about it because they're used to see code like this. func WriteToFile() error {
file, err := os.Open("file.txt")
return errors.Wrap(err, "couldn't open file") if err != nil
defer file.Close()
_, err = file.Write([]byte("Writing something to this file"))
return errors.Wrap(err, "couldn't write to file.txt") if err != nil
return nil
} While reading the third line of code above, you kinda know the return should have an if because you see more code below in the same function. That code would be dead code if the That's how I read Ruby code with early returns: if I see code in the method after the |
I think the problem with this proposal is that you lose the visual cue that something special is happening. Look at a current
Since everything in the |
I think breaking the convention of the You don't know the |
As noted above, the benefits of this proposal seem to be: Making this orthogonal would mean that every statement can have an optional condition, which is a poor fit for the language as it exists today. As @bcmills said above, it is easy to bury important side-effects. -- for @golang/proposal-review |
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:Could be written like this:
Or, to give a more common example:
Could be written as:
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 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, whilereturn
is cleartry
is implicit,return
s are explicittry
disallow doing anything different than just returning the error, while with a plainreturn ... if
people still have control to return a wrapped error or to modify theif
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
if
blocks are easier find while scanning codetry
orhandle
, IMHO)The text was updated successfully, but these errors were encountered: