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: For Else branch #41348

Closed
snadrus opened this issue Sep 11, 2020 · 12 comments
Closed

proposal: Go 2: For Else branch #41348

snadrus opened this issue Sep 11, 2020 · 12 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@snadrus
Copy link

snadrus commented Sep 11, 2020

Whenever a Golang program needs to determine a property of all of a set/list/map/chan, it requires an "if" branch operation on a "found" variable at the end of a loop. Ex:

var found bool
for _, v := haystack {
    if v == needle {
      found = true
      break
    }
}
if !found {  
  // Operation when the set lacks the item
}

With a For-Else construct, this could save a variable, a branch, 3 lines, and has good readability:

for _, v := range haystack {
   if v == needle {
      break
   }
} else {
  // Operation when the set lacks the item   
}

The assembly would be as simple as having break jump to a label below where the end of the For loop jumps to.

Go's overloaded For construct could allow this with Range and it can work with a condition. It has no interesting meaning for unconditional looping. This idea is borrowed from Python.

@gopherbot gopherbot added this to the Proposal milestone Sep 11, 2020
@jcorbin
Copy link

jcorbin commented Sep 11, 2020

Fwiw, such a construct is possible today without the bool or resorting to assembly:

	for _, v := range haystack {
		if v == needle {
			goto next
		}
	}
	// Operation when the set lacks the item

next:
	// either way, we continue here

This sort of Pythonic for/else syntax would merely by sugar.

@fzipp
Copy link
Contributor

fzipp commented Sep 11, 2020

Why not write a contains function, or wait for generics and write a generic contains function?

@ianlancetaylor ianlancetaylor added v2 A language change or incompatible library change LanguageChange labels Sep 11, 2020
@ianlancetaylor
Copy link
Contributor

For language change proposals, please fill out the template at https://go.googlesource.com/proposal/+/refs/heads/master/go2-language-changes.md .

When you are done, please reply to the issue with @gopherbot please remove label WaitingForInfo.

Thanks!

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Sep 11, 2020
@bcmills
Copy link
Contributor

bcmills commented Sep 14, 2020

Compare #24282

@ltto

This comment has been minimized.

@go101
Copy link

go101 commented Sep 15, 2020

I often find I need the following else for form instead:

if len(values) == 0 {
   ... // print some info
} else for _, v := range values {
   ...
}

Surely, currently we can write it as

if len(values) == 0 {
   ... // print some info
}

for _, v := range values {
   ...
}

But I think the former is more logical (and could be a bit more efficient).

If if-block can follow else, why can't others?

[edit]: a better example for the occasion:

if vs := f(); len(vs) == 0 {
} else {
  for _, v := range vs {
  }
}

// vs.

if vs := f(); len(vs) == 0 {
} else for _, v := range vs {
}

@deanveloper
Copy link

I'm personally just not a fan of for else in python. It's very useful, but it just doesn't read well in my opinion and is often a bit confusing.

@gopherbot
Copy link

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@snadrus
Copy link
Author

snadrus commented Oct 19, 2020 via email

@deanveloper
Copy link

deanveloper commented Oct 19, 2020

While that works in that specific example, the general case is a bit more complicated: https://play.golang.org/p/wMaykOGCfMC

The code requires 2 gotos which cross over each other, which can quickly lead to spaghetti code if there is more code in each section other than a simple fmt.Println. If code blocks and indents were used, it would look a lot better (which is the case for for-else). I however think that for-else doesn't look very good and isn't super intuitive. Maybe there is another word which could be used (fallthrough?), as the concept of for-else is very nice, however it just doesn't seem to lead to readable code. Maybe an entirely new concept could be thought up. Or we could just use a found variable for more complicated cases.

@jcorbin
Copy link

jcorbin commented Oct 19, 2020

Maybe there is another word which could be used (fallthrough?)

notwithstanding

@jcorbin
Copy link

jcorbin commented Oct 19, 2020

Looking back at this thread, I'm not sure if anyone's pointed out the precedent of text/template's {{ range }} ... {{ else }} ... {{ end }} ; so there it is fwiw

@golang golang locked and limited conversation to collaborators Oct 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

9 participants