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: spec: finer control of variable scope in if (& other) statements #70337

Closed
1 of 4 tasks
Airblader opened this issue Nov 14, 2024 · 5 comments
Closed
1 of 4 tasks
Labels
LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal
Milestone

Comments

@Airblader
Copy link

Go Programming Experience

Intermediate

Other Languages Experience

No response

Related Idea

  • Has this idea, or one like it, been proposed before?
  • Does this affect error handling?
  • Is this about generics?
  • Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit

Has this idea, or one like it, been proposed before?

No, not that I could find (but tricky to search for).

Does this affect error handling?

No.

Is this about generics?

No.

Proposal

Secondary return values to indicate boolean success or errors are common and idiomatic in Go, in fact much of Go's own standard library uses it. This often leads to code such as

// This could also be "v, err" and "if err != nil".
// someMap := make(map[string]string)

if v, ok := someMap[""]; !ok {
    return
} else {
    // Do something with "v"
}

// Do something else

or an alternate form

v, ok := someMap[""]
if !ok {
    return
}

// Do something with "v"
// Do something else

Both versions have their own upsides and downsides: the former keeps "ok" scoped as narrowly as possible, and leaking variable scope is (anecdotally) a somewhat common source of bugs. On the other hand, the latter reduces mental complexity by avoiding "unnecessary" indentation through the early return, which is commonly a preferred style.

I'd like to propose that the language allows "exporting" (for a lack of better word) a variable defined within the narrower scope to the outer scope, in the above example:

if $v, ok := someMap[""]; !ok {
    return
}

// Do something with "v"
// Do something else

Please note that I'm not proposing $v to be the syntax, it is merely a placeholder. I don't have a good suggestion for what the syntax should be. In any case, to clarify intent, the above would be expected to behave as if it had been

var v string
{
    var ok bool
    if v, ok = someMap[""]; !ok {
        return
    }
}

// Do something with "v"
// Do something else

Disclaimer: This came up internally within our team. I do not think this proposal will reach consensus or even gain notable support, and there are certainly arguments against it such as increased learning cost for relatively minor benefit, or that this could indicate code smell (though I personally disagree on that, but it is hard to argue outside of real-world code bases). However, gauging reactions never hurts.

Language Spec Changes

No response

Informal Change

No response

Is this change backward compatible?

Yes, as it would be an opt-in through new syntax.

Orthogonality: How does this change interact or overlap with existing features?

No response

Would this change make Go easier or harder to learn, and why?

Learning Go from scratch would probably not become notably more difficult as this is an opt-in; however, understanding existing code bases arguably has an additional cost (as every addition to the language does). I think the actual cost here will depend on the syntax, and I don't think it hurts general readability, as the code can still be understood naively, and arguably novice Gophers are already likely to not understand the nuances of variable scope in these situations.

Cost Description

No response

Changes to Go ToolChain

No response

Performance Costs

Minimal compile time cost, no runtime cost.

Prototype

No response

@Airblader Airblader added LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal labels Nov 14, 2024
@gopherbot gopherbot added this to the Proposal milestone Nov 14, 2024
@seankhliao
Copy link
Member

Duplicate of #377

@seankhliao seankhliao marked this as a duplicate of #377 Nov 14, 2024
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Nov 14, 2024
@Airblader
Copy link
Author

@seankhliao I might be misunderstanding, but #377 appears to be about something else (but related) to me.

@seankhliao
Copy link
Member

We've folded similar issues such as #30163 and #61933 into #377,
since they're just the inverse operation, it wouldn't make sense to evaluate them separately.

@Airblader
Copy link
Author

Gotcha, appreciate the reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal
Projects
None yet
Development

No branches or pull requests

4 participants