Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

proposal: spec: Permit range over type sets of rangeable types #71042

Closed
3 of 4 tasks
duckbrain opened this issue Dec 27, 2024 · 2 comments
Closed
3 of 4 tasks

proposal: spec: Permit range over type sets of rangeable types #71042

duckbrain opened this issue Dec 27, 2024 · 2 comments
Labels
LanguageChange Suggested changes to the Go language LanguageChangeReview Discussed by language change review committee Proposal
Milestone

Comments

@duckbrain
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, however there is some overlap in use-cases with #44253

Does this affect error handling?

No

Is this about generics?

Yes, this is lifting a restriction for type sets that contain all rangeable values.

Proposal

Permit using the range operation over a parameterized type set where all types can use the range operation.

For example:

package main

import (
	"cmp"
	"fmt"
)

type List[T cmp.Ordered] interface {
	~[1]T | ~[2]T | ~[3]T | ~[4]T | ~[5]T
}

func CompareLists[T cmp.Ordered, L List[T]](a, b L) int {
	for i := range a {
		if d := cmp.Compare(a[i], b[i]); d != 0 {
			return d
		}
	}
	return 0
}

func main() {
	var a = [...]int{1, 2, 3}
	var b = [...]int{1, 3, 4}

	fmt.Println(CompareLists[int](a, b))
}

Today this code fails to compile with the following message:

./prog.go:13:17: cannot range over a (variable of type L constrained by List[T]): no core type

Per the language specification, range expressions must have specific core types, and type sets of arrays don't have a core type since every size of array is a different underlying type.

Interestingly, both len and the index expression are permitted, so the example code can be rewritten to work using a traditional for loop. This was surprising and it took me reading the language specification to realize that this was another possibility.

func CompareLists[T cmp.Ordered, L List[T]](a, b L) int {
	for i := 0; i < len(a); i++ {
		if d := cmp.Compare(a[i], b[i]); d != 0 {
			return d
		}
	}
	return 0
}

Language Spec Changes

No response

Informal Change

You can now use a range operation on generic types of mixed arrays and slices.

Is this change backward compatible?

Yes

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?

Yes, currently most operations are permitted on parameterized types that are type sets of types that allow that operation. eg: the arithmetic operations, index expressions, and the built-in len function. This removes what appears to be an exception to that rule.

Cost Description

The specification becomes more complicated since the language can no longer lean on the definition of "core type" to describe which parameterized types may use a range operation.

Changes to Go ToolChain

No response

Performance Costs

No response

Prototype

No response

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

I believe this is part of #70128

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Dec 27, 2024
# for free to join this conversation on GitHub. Already have an account? # 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