Skip to content

iter: iter.Seq returns incorrect values for subsequent next calls #64646

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

Closed
j178 opened this issue Dec 11, 2023 · 3 comments
Closed

iter: iter.Seq returns incorrect values for subsequent next calls #64646

j178 opened this issue Dec 11, 2023 · 3 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@j178
Copy link
Contributor

j178 commented Dec 11, 2023

Go version

go version devel go1.22-46ea4ab Sat Dec 9 21:48:06 2023 +0000 darwin/amd64

What operating system and processor architecture are you using (go env)?

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/jo/Library/Caches/go-build'
GOENV='/Users/jo/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT='rangefunc'
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/jo/go/pkg/mod'
GONOPROXY=''
GOOS='darwin'
GOPATH='/Users/jo/go'
GOPRIVATE=''
GOROOT='/Users/jo/sdk/gotip'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/jo/sdk/gotip/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='devel go1.22-46ea4ab Sat Dec 9 21:48:06 2023 +0000'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='0'
GOMOD='/Users/jo/code/it/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/sw/0cn9x8611_xdn6c20pxd96m40000ks/T/go-build14739506649094477967=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

// GOEXPERIMENT=rangefunc

package main

import "iter"

func Range(end int) iter.Seq[int] {
	i := 0
	return func(yield func(int) bool) {
		for ; i < end; i++ {
			if !yield(i) {
				break
			}
		}
	}
}

func Next(seq iter.Seq[int]) (int, bool) {
	for v := range seq {
		return v, true
	}
	return 0, false
}

func main() {
	r := Range(2)

	v, ok := Next(r)
	println(v, ok)
	v, ok = Next(r)
	println(v, ok)
	v, ok = Next(r)
	println(v, ok)
}

What did you expect to see?

0 true
1 true
0 false

What did you see instead?

0 true
0 true
0 true
@gophun
Copy link

gophun commented Dec 11, 2023

You're restarting iteration with each range. If you want to turn the push-based iter.Seq into a pull-based iterator use the iter.Pull function on it.

@prattmic prattmic added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 11, 2023
@prattmic prattmic added this to the Go1.23 milestone Dec 11, 2023
@prattmic
Copy link
Member

cc @rsc

@j178
Copy link
Contributor Author

j178 commented Dec 12, 2023

I realized that the yield function always returns false, the loop never progresses beyond the first iteration, resulting in an infinite sequence of 0. The corrected implementaion of Range:

func Range(end int) iter.Seq[int] {
	i := 0
	return func(yield func(int) bool) {
		for ; i < end; i++ {
			if !yield(i) {
				i++ // proceed here
				break
			}
		}
	}
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants