Open4

GoのGenerics関連のAcceptされたProposalを全部紹介する会 発表資料

syumaisyumai

目次

初めに読むべきもの

  • go: don't change the libraries in 1.18

各Proposalの紹介

  • type parameters (軽めに)
  • type sets (軽めに)
  • constraints package
  • slices package
  • go/ast changes for generics
  • maps package
  • sort: generic functions
  • allow 'any' for 'interface{}' in non-constraint contexts
  • type parameters on aliases
  • allow eliding interface{ } in constraint literals
  • go/types changes for generics

その他

Discussion

資料集

宣伝

  • GoConの登壇告知
  • #gospecreading のイベント告知
syumaisyumai

初めに読むべきもの

go: don't change the libraries in 1.18 (#48918)

https://github.com/golang/go/issues/48918

(注) この内容は決定事項ではなく、まだ議論中です

Rob Pikeによる提案で、Go 1.18では標準ライブラリを更新するのをやめたい、と言う内容。
Go 1.18は、Go言語が作られて以来最も大きな変更になるので、1度に全てを行うと判断を誤る可能性があるのでは、といった文脈で提案が出ている。
標準ライブラリに対する変更を行うと、後方互換性を保つ責任も発生する。
そのため、直接標準ライブラリを更新するのではなく、まずは、 golang.org/x/exp に入れて様子を見たい、と言うことが提案されている。

https://github.com/golang/exp

exp packageは、標準化されていないpackageが置かれている golang.org/x よりも更に試験的なもの、と言う扱い。
標準ライブラリにGenericsに関するpackageが入らなかったとしても、expから使えるので利便性は損なわないはず、と言う主張。

この提案内容が通ったら、これから説明する標準ライブラリに関するProposalの内容は、Acceptされているにも関わらずGo 1.18では標準ライブラリに入らない可能性があります

(個人的には、このIssueの内容には賛成です)

syumaisyumai

各Proposalの紹介

type parameters: accepted (2021/2/11)

https://github.com/golang/go/issues/43651

Goでジェネリックなプログラミングを行えるようにするために、型や関数が type parameter を受け付けることを出来るようにする提案です。
型パラメータが受け付ける型に対しての constraints の導入や、型推論のルールについてもこの提案に含まれています。

tenntennさんの資料 によくまとまっています

Proposal内[1]のコード例

// Stringer is a type constraint that requires the type argument to have
// a String method and permits the generic function to call String.
// The String method should return a string representation of the value.
type Stringer interface {
	String() string
}
// Stringify calls the String method on each element of s,
// and returns the results.
func Stringify[T Stringer](s []T) (ret []string) {
	for _, v := range s {
		ret = append(ret, v.String())
	}
	return ret
}

type sets: accepted (2021/7/22)

https://github.com/golang/go/issues/45346

Nobishiiさんの資料 によくまとまっています

type parameters proposalがacceptされた時点で含まれていた、constraintsにおける type list を置き換える提案です。
type listのわかりにくさを解消し、より一般的な解決法を提案したもので、2021年7月にacceptされました。

コード例

type PredeclaredSignedInteger interface {
	int | int8 | int16 | int32 | int64
}
type SignedInteger interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

constraints package: accepted (2021/8/19)

https://github.com/golang/go/issues/45458

頻繁に使われるであろう制約の定義をまとめたpackageです。
過去の記事で詳しく紹介しています。

このProposalはAcceptされましたが、 #47916 で一部定義の置き換えが行われそうです。

slices package: accepted (2021/8/12)

https://github.com/golang/go/issues/45955

sliceをジェネリックに操作したい時に使うpackageです。
過去の記事で詳しく紹介しています。

go/ast changes for generics: accepted (2021/9/16)

静的解析関連のpackage、go/ast に対する変更。
(DQNEOさんと読みます)

https://github.com/golang/go/issues/47781

https://go.googlesource.com/proposal/+/master/design/47781-parameterized-go-ast.md

maps package: accepted (2021/9/23)

https://github.com/golang/go/issues/47649

mapをジェネリックに操作したい時に使うpackageです。
過去の記事で詳しく紹介しています。

sort: generic functions: accepted (2021/9/23)

https://github.com/golang/go/issues/47619

sliceをジェネリックにソートしたい時に使う関数群です。
提案は、 sort.SliceOf という sort package への変更という形で出されましたが、Russ Coxのコメントを受けて、slices packageの変更となりました。

Russ Coxのコメント: https://github.com/golang/go/issues/47619#issuecomment-897042602

最終的な形はこちらです。

package slices

func Sort[Elem constraints.Ordered](x []Elem)
func SortFunc[Elem any](x []Elem, less func(a, b Elem) bool)
func SortStable[Elem constraints.Ordered](x []Elem)
func SortStableFunc[Elem any](x []Elem, less func(a, b Elem) bool)
func IsSorted[Elem constraints.Ordered](x []Elem)
func IsSortedFunc[Elem any](x []Elem, less func(a, b Elem) bool)

func BinarySearch[Elem constraints.Ordered](x Slice, target Elem) int
func BinarySearchFunc[Elem any](x []Elem, ok func(Elem) bool) int

spec: generics: type parameters on aliases: accepted (2021/9/23)

https://github.com/golang/go/issues/46477

spec: allow eliding interface{ } in constraint literals: accepted (2021/10/14)

https://github.com/golang/go/issues/48424

go/types changes for generics: accepted (2021/10/14)

https://github.com/golang/go/issues/47916

https://go.googlesource.com/proposal/+/master/design/47916-parameterized-go-types.md

脚注
  1. https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md ↩︎