diff --git a/design/go2draft-type-parameters.md b/design/go2draft-type-parameters.md
new file mode 100644
index 0000000..d6ade68
--- /dev/null
+++ b/design/go2draft-type-parameters.md
@@ -0,0 +1,3510 @@
+# Type Parameters - Draft Design
+
+Ian Lance Taylor\
+Robert Griesemer\
+June 16, 2020
+
+## Abstract
+
+We suggest extending the Go language to add optional type parameters
+to types and functions.
+Type parameters may be constrained by interface types.
+We also suggest extending interface types, when used as type
+constraints, to permit listing the set of types that may be assigned
+to them.
+Type inference via a unification algorithm is supported to permit
+omitting type arguments from function calls in many cases.
+The design is fully backward compatible with Go 1.
+
+## How to read this design draft
+
+This document is long.
+Here is some guidance on how to read it.
+
+* We start with a high level overview, describing the concepts very
+  briefly.
+* We then explain the full design starting from scratch, introducing
+  the details as we need them, with simple examples.
+* After the design is completely described, we discuss implementation,
+  some issues with the design, and a comparison with other approaches
+  to generics.
+* We then present several complete examples of how this design would
+  be used in practice.
+* Following the examples some minor details are discussed in an
+  appendix.
+
+## Very high level overview
+
+This section explains the changes suggested by the design draft very
+briefly.
+This section is intended for people who are already familiar with how
+generics would work in a language like Go.
+These concepts will be explained in detail in the following sections.
+
+* Functions can have an additional type parameter list introduced by
+  the keyword `type`: `func F(type T)(p T) { ... }`.
+* These type parameters can be used by the regular parameters and in
+  the function body.
+* Types can also have a type parameter list: `type M(type T) []T`.
+* Each type parameter can have an optional type constraint: `func
+  F(type T Constraint)(p T) { ... }`
+* Type constraints are interface types.
+* Interface types used as type constraints can have a list of
+  predeclared types; only types whose underlying type is one of those
+  types can implement the interface.
+* Using a generic function or type requires passing type arguments.
+* Type inference permits omitting the type arguments in common cases.
+* If a type parameter has a type constraint its type argument must
+  implement the interface.
+* Generic functions may only use operations permitted by the type
+  constraint.
+
+In the following sections we work through each of these language
+changes in great detail.
+You may prefer to skip ahead to the [examples](#Examples) to see what
+generic code written to this design draft will look like in practice.
+
+## Background
+
+This version of the design draft has many similarities to the one
+presented on July 31, 2019, but contracts have been removed and
+replaced by interface types.
+
+There have been many [requests to add additional support for generic
+programming](https://github.com/golang/go/wiki/ExperienceReports#generics)
+in Go.
+There has been extensive discussion on
+[the issue tracker](https://golang.org/issue/15292) and on
+[a living document](https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/view).
+
+There have been several proposals for adding type parameters, which
+can be found through the links above.
+Many of the ideas presented here have appeared before.
+The main new features described here are the syntax and the careful
+examination of interface types as constraints.
+
+This design draft suggests extending the Go language to add a form of
+parametric polymorphism, where the type parameters are bounded not by
+a declared subtyping relationship (as in some object oriented
+languages) but by explicitly defined structural constraints.
+
+This design does not support template metaprogramming or any other
+form of compile time programming.
+
+As the term _generic_ is widely used in the Go community, we will
+use it below as a shorthand to mean a function or type that takes type
+parameters.
+Don't confuse the term generic as used in this design with the same
+term in other languages like C++, C#, Java, or Rust; they have
+similarities but are not the same.
+
+## Design
+
+We will describe the complete design in stages based on simple
+examples.
+
+### Type parameters
+
+Generic code is code that is written using types that will be
+specified later.
+An unspecified type is called a _type parameter_.
+When running the generic code, the type parameter will be set to a
+_type argument_.
+
+Here is a function that prints out each element of a slice, where the
+element type of the slice, here called `T`, is unknown.
+This is a trivial example of the kind of function we want to permit in
+order to support generic programming.
+(Later we'll also discuss [generic types](#Generic types)).
+
+```Go
+// Print prints the elements of a slice.
+// It should be possible to call this with any slice value.
+func Print(s []T) { // Just an example, not the suggested syntax.
+	for _, v := range s {
+		fmt.Println(v)
+	}
+}
+```
+
+With this approach, the first decision to make is: how should the type
+parameter `T` be declared?
+In a language like Go, we expect every identifier to be declared in
+some way.
+
+Here we make a design decision: type parameters are similar to
+ordinary non-type function parameters, and as such should be listed
+along with other parameters.
+However, type parameters are not the same as non-type parameters, so
+although they appear in the list of parameters we want to distinguish
+them.
+That leads to our next design decision: we define an additional,
+optional, parameter list, describing type parameters.
+This parameter list appears before the regular parameters.
+It starts with the keyword `type`, and lists type parameters.
+
+```Go
+// Print prints the elements of any slice.
+// Print has a type parameter T, and has a single (non-type)
+// parameter s which is a slice of that type parameter.
+func Print(type T)(s []T) {
+	// same as above
+}
+```
+
+This says that within the function `Print` the identifier `T` is a
+type parameter, a type that is currently unknown but that will be
+known when the function is called.
+As seen above, the type parameter may be used as a type when
+describing the ordinary non-type parameters.
+It may also be used within the body of the function.
+
+Since `Print` has a type parameter, any call of `Print` must provide a
+type argument.
+Later we will see how this type argument can usually be deduced from
+the non-type argument, by using [function argument type
+inference](#Function argument type inference).
+For now, we'll pass the type argument explicitly.
+Type arguments are passed much like type parameters are declared: as a
+separate list of arguments.
+At the call site, the `type` keyword is not used.
+
+```Go
+	// Call Print with a []int.
+	// Print has a type parameter T, and we want to pass a []int,
+	// so we pass a type argument of int by writing Print(int).
+	// The function Print(int) expects a []int as an argument.
+
+	Print(int)([]int{1, 2, 3})
+
+	// This will print:
+	// 1
+	// 2
+	// 3
+```
+
+### Constraints
+
+Let's make our example slightly more complicated.
+Let's turn it into a function that converts a slice of any type into a
+`[]string` by calling a `String` method on each element.
+
+```Go
+// This function is INVALID.
+func Stringify(type T)(s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String()) // INVALID
+	}
+	return ret
+}
+```
+
+This might seem OK at first glance, but in this example `v` has type
+`T`, and we don't know anything about `T`.
+In particular, we don't know that `T` has a `String` method.
+So the call to `v.String()` is invalid.
+
+Naturally, the same issue arises in other languages that support
+generic programming.
+In C++, for example, a generic function (in C++ terms, a function
+template) can call any method on a value of generic type.
+That is, in the C++ approach, calling `v.String()` is fine.
+If the function is called with a type argument that does not have a
+`String` method, the error is reported when compiling the call to
+`v.String` with that type argument.
+These errors can be lengthy, as there may be several layers of generic
+function calls before the error occurs, all of which must be reported
+to understand what went wrong.
+
+The C++ approach would be a poor choice for Go.
+One reason is the style of the language.
+In Go we don't refer to names, such as, in this case, `String`, and
+hope that they exist.
+Go resolves all names to their declarations when they are seen.
+
+Another reason is that Go is designed to support programming at
+scale.
+We must consider the case in which the generic function definition
+(`Stringify`, above) and the call to the generic function (not shown,
+but perhaps in some other package) are far apart.
+In general, all generic code expects the type arguments to meet
+certain requirements.
+We refer to these requirements as _constraints_ (other languages have
+similar ideas known as type bounds or trait bounds or concepts).
+In this case, the constraint is pretty obvious: the type has to have a
+`String() string` method.
+In other cases it may be much less obvious.
+
+We don't want to derive the constraints from whatever `Stringify`
+happens to do (in this case, call the `String` method).
+If we did, a minor change to `Stringify` might change the
+constraints.
+That would mean that a minor change could cause code far away, that
+calls the function, to unexpectedly break.
+It's fine for `Stringify` to deliberately change its constraints, and
+force users to change.
+What we want to avoid is `Stringify` changing its constraints
+accidentally.
+
+This means that the constraints must set limits on both the type
+arguments passed by the caller and the code in the generic function.
+The caller may only pass type arguments that satisfy the constraints.
+The generic function may only use those values in ways that are
+permitted by the constraints.
+This is an important rule that we believe should apply to any attempt
+to define generic programming in Go: generic code can only use
+operations that its type arguments are known to implement.
+
+### Operations permitted for any type
+
+Before we discuss constraints further, let's briefly note what happens
+in their absence.
+If a generic function does not specify a constraint for a type
+parameter, as is the case for the `Print` method above, then any type
+argument is permitted for that parameter.
+The only operations that the generic function can use with values of
+that type parameter are those operations that are permitted for values
+of any type.
+In the example above, the `Print` function declares a variable `v`
+whose type is the type parameter `T`, and it passes that variable to a
+function.
+
+The operations permitted for any type are:
+
+* declare variables of those types
+* assign other values of the same type to those variables
+* pass those variables to functions or return them from functions
+* take the address of those variables
+* convert or assign values of those types to the type `interface{}`
+* convert a value of type `T` to type `T` (permitted but useless)
+* use a type assertion to convert an interface value to the type
+* use the type as a case in a type switch
+* define and use composite types that use those types, such as a slice
+  of that type
+* pass the type to some builtin functions such as `new`
+
+It's possible that future language changes will add other such
+operations, though none are currently anticipated.
+
+### Defining constraints
+
+Go already has a construct that is close to what we need for a
+constraint: an interface type.
+An interface type is a set of methods.
+The only values that can be assigned to a variable of interface type
+are those whose types implement the same methods.
+The only operations that can be done with a value of interface type,
+other than operations permitted for any type, are to call the
+methods.
+
+Calling a generic function with a type argument is similar to
+assigning to a variable of interface type: the type argument must
+implement the constraints of the type parameter.
+Writing a generic function is like using values of interface type: the
+generic code can only use the operations permitted by the constraint
+(or operations that are permitted for any type).
+
+In this design, constraints are simply interface types.
+Implementing a constraint is simply implementing the interface type.
+(Later we'll see how to define constraints for operations other than
+method calls, such as [binary operators](#Operators)).
+
+For the `Stringify` example, we need an interface type with a `String`
+method that takes no arguments and returns a value of type `string`.
+
+```Go
+// 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
+}
+```
+
+(It doesn't matter for this discussion, but this defines the same
+interface as the standard library's `fmt.Stringer` type, and  real
+code would likely simply use `fmt.Stringer`.)
+
+### Using a constraint
+
+For a generic function, a constraint can be thought of as the type of
+the type argument: a meta-type.
+So, although generic functions are not required to use constraints,
+when they do they are listed in the type parameter list as the
+meta-type of a type parameter.
+
+```Go
+// Stringify calls the String method on each element of s,
+// and returns the results.
+func Stringify(type T Stringer)(s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String())
+	}
+	return ret
+}
+```
+
+The single type parameter `T` is followed by the constraint that
+applies to `T`, in this case `Stringer`.
+
+### Multiple type parameters
+
+Although the `Stringify` example uses only a single type parameter,
+functions may have multiple type parameters.
+
+```Go
+// Print2 has two type parameters and two non-type parameters.
+func Print2(type T1, T2)(s1 []T1, s2 []T2) { ... }
+```
+
+Compare this to
+
+```Go
+// Print2Same has one type parameter and two non-type parameters.
+func Print2Same(type T)(s1 []T, s2 []T) { ... }
+```
+
+In `Print2` `s1` and `s2` may be slices of different types.
+In `Print2Same` `s1` and `s2` must be slices of the same element
+type.
+
+Each type parameter may have its own constraint.
+
+```Go
+// Stringer is a type constraint that requires a String method.
+// The String method should return a string representation of the value.
+type Stringer interface {
+	String() string
+}
+
+// Plusser is a type constraint that requires a Plus method.
+// The Plus method is expected to add the argument to an internal
+// string and return the result.
+type Plusser interface {
+	Plus(string) string
+}
+
+// ConcatTo takes a slice of elements with a String method and a slice
+// of elements with a Plus method. The slices should have the same
+// number of elements. This will convert each element of s to a string,
+// pass it to the Plus method of the corresponding element of p,
+// and return a slice of the resulting strings.
+func ConcatTo(type S Stringer, P Plusser)(s []S, p []P) []string {
+	r := make([]string, len(s))
+	for i, v := range s {
+		r[i] = p[i].Plus(v.String())
+	}
+	return r
+}
+```
+
+If a constraint is specified for any type parameter, every type
+parameter must have a constraint.
+If some type parameters need a constraint and some do not, those that
+do not should have a constraint of `interface{}`.
+
+```Go
+// StrAndPrint takes a slice of labels, which can be any type,
+// and a slice of values, which must have a String method,
+// converts the values to strings, and prints the labelled strings.
+func StrAndPrint(type L interface{}, T Stringer)(labels []L, vals []T) {
+	// Stringify was defined above. It returns a []string.
+	for i, s := range Stringify(vals) {
+		fmt.Println(labels[i], s)
+	}
+}
+```
+
+A single constraint can be used for multiple type parameters, just as
+a single type can be used for multiple non-type function parameters.
+The constraint applies to each type parameter separately.
+
+```Go
+// Stringify2 converts two slices of different types to strings,
+// and returns the concatenation of all the strings.
+func Stringify2(type T1, T2 Stringer)(s1 []T1, s2 []T2) string {
+	r := ""
+	for _, v1 := range s1 {
+		r += v1.String()
+	}
+	for _, v2 := range s2 {
+		r += v2.String()
+	}
+	return r
+}
+```
+
+### Generic types
+
+We want more than just generic functions: we also want generic types.
+We suggest that types be extended to take type parameters.
+
+```Go
+// Vector is a name for a slice of any element type.
+type Vector(type T) []T
+```
+
+A type's parameters are just like a function's type parameters.
+
+Within the type definition, the type parameters may be used like any
+other type.
+
+To use a generic type, you must supply type arguments.
+This looks like a function call, except that the function in this case
+is actually a type.
+This is called _instantiation_.
+When we instantiate a type by supplying type arguments for the type
+parameters, we produce a type in which each use of a type parameter in
+the type definition is replaced by the corresponding type argument.
+
+```Go
+// v is a Vector of int values.
+//
+// This is similar to pretending that "Vector(int)" is a valid identifier,
+// and writing
+//   type "Vector(int)" []int
+//   var v "Vector(int)"
+// All uses of Vector(int) will refer to the same "Vector(int)" type.
+//
+var v Vector(int)
+```
+
+Generic types can have methods.
+The receiver type of a method must declare the same number of type
+parameters as are declared in the receiver type's definition.
+They are declared without the `type` keyword or any constraint.
+
+```Go
+// Push adds a value to the end of a vector.
+func (v *Vector(T)) Push(x T) { *v = append(*v, x) }
+```
+
+The type parameters listed in a method declaration need not have the
+same names as the type parameters in the type declaration.
+In particular, if they are not used by the method, they can be `_`.
+
+A generic type can refer to itself in cases where a type can
+ordinarily refer to itself, but when it does so the type arguments
+must be the type parameters, listed in the same order.
+This restriction prevents infinite recursion of type instantiation.
+
+```Go
+// List is a linked list of values of type T.
+type List(type T) struct {
+	next *List(T) // this reference to List(T) is OK
+	val  T
+}
+
+// This type is INVALID.
+type P(type T1, T2) struct {
+	F *P(T2, T1) // INVALID; must be (T1, T2)
+}
+```
+
+This restriction applies to both direct and indirect references.
+
+```Go
+// ListHead is the head of a linked list.
+type ListHead(type T) struct {
+	head *ListElement(T)
+}
+
+// ListElement is an element in a linked list with a head.
+// Each element points back to the head.
+type ListElement(type T) struct {
+	next *ListElement(T)
+	val  T
+	// Using ListHead(T) here is OK.
+	// ListHead(T) refers to ListElement(T) refers to ListHead(T).
+	// Using ListHead(int) would not be OK, as ListHead(T)
+	// would have an indirect reference to ListHead(int).
+	head *ListHead(T)
+}
+```
+
+(Note: with more understanding of how people want to write code, it
+may be possible to relax this rule to permit some cases that use
+different type arguments.)
+
+The type parameter of a generic type may have constraints.
+
+```Go
+// StringableVector is a slice of some type, where the type
+// must have a String method.
+type StringableVector(type T Stringer) []T
+
+func (s StringableVector(T)) String() string {
+	var sb strings.Builder
+	for i, v := range s {
+		if i > 0 {
+			sb.WriteString(", ")
+		}
+		// It's OK to call v.String here because v is of type T
+		// and T's constraint is Stringer.
+		sb.WriteString(v.String())
+	}
+	return sb.String()
+}
+```
+
+### Methods may not take additional type arguments
+
+Although methods of a generic type may use the type's parameters,
+methods may not themselves have additional type parameters.
+Where it would be useful to add type arguments to a method, people
+will have to write a suitably parameterized top-level function.
+
+This is not a fundamental restriction but it complicates the language
+specification and the implementation.
+
+(Note: this is a feature that can perhaps be added later if it proves
+necessary.)
+
+### Operators
+
+As we've seen, we are using interface types as constraints.
+Interface types provide a set of methods, and nothing else.
+This means that with what we've seen so far, the only thing that
+generic functions can do with values of type parameters, other than
+operations that are permitted for any type, is call methods.
+
+However, method calls are not sufficient for everything we want to
+express.
+Consider this simple function that returns the smallest element of a
+slice of values, where the slice is assumed to be non-empty.
+
+```Go
+// This function is INVALID.
+func Smallest(type T)(s []T) T {
+	r := s[0] // panic if slice is empty
+	for _, v := range s[1:] {
+		if v < r { // INVALID
+			r = v
+		}
+	}
+	return r
+}
+```
+
+Any reasonable generics implementation should let you write this
+function.
+The problem is the expression `v < r`.
+This assumes that `T` supports the `<` operator, but `T` has no
+constraint.
+Without a constraint the function `Smallest` can only use operations
+that are available for all types, but not all Go types support `<`.
+Unfortunately, since `<` is not a method, there is no obvious way to
+write a constraint&mdash;an interface type&mdash;that permits `<`.
+
+We need a way to write a constraint that accepts only types that
+support `<`.
+In order to do that, we observe that, aside from two exceptions that
+we will discuss later, all the arithmetic, comparison, and logical
+operators defined by the language may only be used with types that are
+predeclared by the language, or with defined types whose underlying
+type is one of those predeclared types.
+That is, the operator `<` can only be used with a predeclared type
+such as `int` or `float64`, or a defined type whose underlying type is
+one of those types.
+Go does not permit using `<` with a composite type or with an
+arbitrary defined type.
+
+This means that rather than try to write a constraint for `<`, we can
+approach this the other way around: instead of saying which operators
+a constraint should support, we can say which (underlying) types a
+constraint should accept.
+
+#### Type lists in constraints
+
+An interface type used as a constraint may list explicit types that
+may be used as type arguments.
+This is done using the `type` keyword followed by a comma-separated
+list of types.
+
+For example:
+
+```Go
+// SignedInteger is a type constraint that permits any
+// signed integer type.
+type SignedInteger interface {
+	type int, int8, int16, int32, int64
+}
+```
+
+The `SignedInteger` constraint specifies that the type argument
+must be one of the listed types.
+More precisely, the underlying type of the type argument must be
+identical to the underlying type of one of the types in the type
+list.
+This means that `SignedInteger` will accept the listed integer types,
+and will also accept any type that is defined as one of those types.
+
+When a generic function uses a type parameter with one of these
+constraints, it may use any operation that is permitted by all of the
+listed types.
+This can be an operation like `<`, `range`, `<-`, and so forth.
+If the function can be compiled successfully using each type listed in
+the constraint, then the operation is permitted.
+
+A constraint may only have one type list.
+
+For the `Smallest` example shown earlier, we could use a constraint
+like this:
+
+```Go
+package constraints
+
+// Ordered is a type constraint that matches any ordered type.
+// An ordered type is one that supports the <, <=, >, and >= operators.
+type Ordered interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		string
+}
+```
+
+In practice this constraint would likely be defined and exported in a
+new standard library package, `constraints`, so that it could be used
+by function and type definitions.
+
+Given that constraint, we can write this function, now valid:
+
+```Go
+// Smallest returns the smallest element in a slice.
+// It panics if the slice is empty.
+func Smallest(type T constraints.Ordered)(s []T) T {
+	r := s[0] // panics if slice is empty
+	for _, v := range s[1:] {
+		if v < r {
+			r = v
+		}
+	}
+	return r
+}
+```
+
+#### Comparable types in constraints
+
+Earlier we mentioned that there are two exceptions to the rule that
+operators may only be used with types that are predeclared by the
+language.
+The exceptions are `==` and `!=`, which are permitted for struct,
+array, and interface types.
+These are useful enough that we want to be able to write a constraint
+that accepts any comparable type.
+
+To do this we introduce a new predeclared type constraint:
+`comparable`.
+A type parameter with the `comparable` constraint accepts as a type
+argument any comparable type.
+It permits the use of `==` and `!=` with values of that type parameter.
+
+For example, this function may be instantiated with any comparable
+type:
+
+```Go
+// Index returns the index of x in s, or -1 if not found.
+func Index(type T comparable)(s []T, x T) int {
+	for i, v := range s {
+		// v and x are type T, which has the comparable
+		// constraint, so we can use == here.
+		if v == x {
+			return i
+		}
+	}
+	return -1
+}
+```
+
+Since `comparable`, like all constraints, is an interface type, it can
+be embedded in another interface type used as a constraint:
+
+```Go
+// ComparableHasher is a type constraint that matches all
+// comparable types with a Hash method.
+type ComparableHasher interface {
+	comparable
+	Hash() uintptr
+}
+```
+
+The constraint `ComparableHasher` is implemented by any type that is
+comparable and also has a `Hash() uintptr` method.
+A generic function that uses `ComparableHasher` as a constraint can
+compare values of that type and can call the `Hash` method.
+
+#### Type lists in interface types
+
+Interface types with type lists may only be used as constraints on
+type parameters.
+They may not be used as ordinary interface types.
+The same is true of the predeclared interface type `comparable`.
+
+This restriction may be lifted in future language versions.
+An interface type with a type list may be useful as a form of sum
+type, albeit one that can have the value `nil`.
+Some alternative syntax would likely be required to match on identical
+types rather than on underlying types; perhaps `type ==`.
+For now, this is not permitted.
+
+### Function argument type inference
+
+In many cases, when calling a function with type parameters, we can
+use type inference to avoid having to explicitly write out the type
+arguments.
+
+Go back to [the example](#Type parameters) of a call to the simple
+`Print` function:
+
+```Go
+	Print(int)([]int{1, 2, 3})
+```
+
+The type argument `int` in the function call can be inferred from the
+type of the non-type argument.
+
+This can only be done when all the function's type parameters are used
+for the types of the function's (non-type) input parameters.
+If there are some type parameters that are used only for the
+function's result parameter types, or only in the body of the
+function, then our algorithm does not infer the type arguments for the
+function, since there is no value from which to infer the types.
+
+When the function's type arguments can be inferred, the language uses
+type unification.
+On the caller side we have the list of types of the actual (non-type)
+arguments, which for the `Print` example is simply `[]int`.
+On the function side is the list of the types of the function's
+non-type parameters, which for `Print` is `[]T`.
+In the lists, we discard respective arguments for which the function
+side does not use a type parameter.
+We must then unify the remaining argument types.
+
+Type unification is a two-pass algorithm.
+In the first pass, we ignore untyped constants on the caller side and
+their corresponding types in the function definition.
+
+We compare corresponding types in the lists.
+Their structure must be identical, except that type parameters on the
+function side match the type that appears on the caller side at the
+point where the type parameter occurs.
+If the same type parameter appears more than once on the function
+side, it will match multiple argument types on the caller side.
+Those caller types must be identical, or type unification fails, and
+we report an error.
+
+After the first pass, we check any untyped constants on the caller
+side.
+If there are no untyped constants, or if the type parameters in the
+corresponding function types have matched other input types, then
+type unification is complete.
+
+Otherwise, for the second pass, for any untyped constants whose
+corresponding function types are not yet set, we determine the default
+type of the untyped constant in [the usual
+way](https://golang.org/ref/spec#Constants).
+Then we run the type unification algorithm again, this time with no
+untyped constants.
+
+In this example
+
+```Go
+	s1 := []int{1, 2, 3}
+	Print(s1)
+```
+
+we compare `[]int` with `[]T`, match `T` with `int`, and we are done.
+The single type parameter `T` is `int`, so we infer that the call to
+`Print` is really a call to `Print(int)`.
+
+For a more complex example, consider
+
+```Go
+// Map calls the function f on every element of the slice s,
+// returning a new slice of the results.
+func Map(type F, T)(s []F, f func(F) T) []T {
+	r := make([]T, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+```
+
+The two type parameters `F` and `T` are both used for input
+parameters, so type inference is possible.
+In the call
+
+```Go
+	strs := Map([]int{1, 2, 3}, strconv.Itoa)
+```
+
+we unify `[]int` with `[]F`, matching `F` with `int`.
+We unify the type of `strconv.Itoa`, which is `func(int) string`,
+with `func(F) T`, matching `F` with `int` and `T` with `string`.
+The type parameter `F` is matched twice, both times with `int`.
+Unification succeeds, so the call written as `Map` is a call of
+`Map(int, string)`.
+
+To see the untyped constant rule in effect, consider:
+
+```Go
+// NewPair returns a pair of values of the same type.
+func NewPair(type F)(f1, f2 F) *Pair(F) { ... }
+```
+
+In the call `NewPair(1, 2)` both arguments are untyped constants, so
+both are ignored in the first pass.
+There is nothing to unify.
+We still have two untyped constants after the first pass.
+Both are set to their default type, `int`.
+The second run of the type unification pass unifies `F` with
+`int`, so the final call is `NewPair(int)(1, 2)`.
+
+In the call `NewPair(1, int64(2))` the first argument is an untyped
+constant, so we ignore it in the first pass.
+We then unify `int64` with `F`.
+At this point the type parameter corresponding to the untyped constant
+is fully determined, so the final call is `NewPair(int64)(1,
+int64(2))`.
+
+In the call `NewPair(1, 2.5)` both arguments are untyped constants,
+so we move on the second pass.
+This time we set the first constant to `int` and the second to
+`float64`.
+We then try to unify `F` with both `int` and `float64`, so unification
+fails, and we report a compilation error.
+
+Note that type inference is done without regard to constraints.
+First we use type inference to determine the type arguments to use for
+the function, and then, if that succeeds, we check whether those type
+arguments implement the constraints (if any).
+
+Note that after successful type inference, the compiler must still
+check that the arguments can be assigned to the parameters, as for any
+function call.
+
+(Note: type inference is a convenience feature.
+Although we think it is an important feature, it does not add any
+functionality to the design, only convenience in using it.
+It would be possible to omit it from the initial implementation, and
+see whether it seems to be needed.
+That said, this feature doesn't require additional syntax, and
+produces more readable code.)
+
+### Using types that refer to themselves in constraints
+
+It can be useful for a generic function to require a type argument
+with a method whose argument is the type itself.
+For example, this arises naturally in comparison methods.
+(Note that we are talking about methods here, not operators.)
+Suppose we want to write an `Index` method that uses an `Equal` method
+to check whether it has found the desired value.
+We would like to write that like this:
+
+```Go
+// Index returns the index of e in s, or -1 if not found.
+func Index(type T Equaler)(s []T, e T) int {
+	for i, v := range s {
+		if e.Equal(v) {
+			return i
+		}
+	}
+	return -1
+}
+```
+
+In order to write the `Equaler` constraint, we have to write a
+constraint that can refer to the type argument being passed in.
+There is no way to do that directly, but what we can do is write an
+interface type that use a type parameter.
+
+```Go
+// Equaler is a type constraint for types with an Equal method.
+type Equaler(type T) interface {
+	Equal(T) bool
+}
+```
+
+To make this work, `Index` will pass `T` as the type argument to
+`Equaler`.
+The rule is that if a type contraint has a single type parameter, and
+it is used in a function's type parameter list without an explicit
+type argument, then the type argument is the type parameter being
+constrained.
+In other words, in the definition of `Index` above, the constraint
+`Equaler` is treated as `Equaler(T)`.
+
+This version of `Index` would be used with a type like `equalInt`
+defined here:
+
+```Go
+// equalInt is a version of int that implements Equaler.
+type equalInt int
+
+// The Equal method lets equalInt implement the Equaler constraint.
+func (a equalInt) Equal(b equalInt) bool { return a == b }
+
+// indexEqualInts returns the index of e in s, or -1 if not found.
+func indexEqualInt(s []equalInt, e equalInt) int {
+	return Index(equalInt)(s, e)
+}
+```
+
+In this example, when we pass `equalInt` to `Index`, we check whether
+`equalInt` implements the constraint `Equaler`.
+Since `Equaler` has a type parameter, we pass the type argument of
+`Index`, which is `equalInt`, as the type argument to `Equaler`.
+The constraint is, then, `Equaler(equalInt)`, which is satisfied
+by any type with a method `Equal(equalInt) bool`.
+The `equalInt` type has a method `Equal` that accepts a parameter of
+type `equalInt`, so all is well, and the compilation succeeds.
+
+### Mutually referencing type parameters
+
+Within a single type parameter list, constraints may refer to any of
+the other type parameters, even ones that are declared later in the
+same list.
+(The scope of a type parameter starts at the `type` keyword of the
+parameter list and extends to the end of the enclosing function or
+type declaration.)
+
+For example, consider a generic graph package that contains generic
+algorithms that work with graphs.
+The algorithms use two types, `Node` and `Edge`.
+`Node` is expected to have a method `Edges() []Edge`.
+`Edge` is expected to have a method `Nodes() (Node, Node)`.
+A graph can be represented as a `[]Node`.
+
+This simple representation is enough to implement graph algorithms
+like finding the shortest path.
+
+```Go
+package graph
+
+// NodeConstraint is the type constraint for graph nodes:
+// they must have an Edges method that returns the Edge's
+// that connect to this Node.
+type NodeConstraint(type Edge) interface {
+	Edges() []Edge
+}
+
+// EdgeConstraint is the type constraint for graph edges:
+// they must have a Nodes method that returns the two Nodes
+// that this edge connects.
+type EdgeConstraint(type Node) interface {
+	Nodes() (from, to Node)
+}
+
+// Graph is a graph composed of nodes and edges.
+type Graph(type Node NodeConstraint(Edge), Edge EdgeConstraint(Node)) struct { ... }
+
+// New returns a new graph given a list of nodes.
+func New(
+	type Node NodeConstraint(Edge), Edge EdgeConstraint(Node)) (
+	nodes []Node) *Graph(Node, Edge) {
+	...
+}
+
+// ShortestPath returns the shortest path between two nodes,
+// as a list of edges.
+func (g *Graph(Node, Edge)) ShortestPath(from, to Node) []Edge { ... }
+```
+
+There are a lot of type arguments and instantiations here.
+In the constraint on `Node` in `Graph`, the `Edge` being passed to the
+type constraint `NodeConstraint` is the second type parameter of
+`Graph`.
+This instantiates `NodeConstraint` with the type parameter `Edge`, so
+we see that `Node` must have a method `Edges` that returns a slice of
+`Edge`, which is what we want.
+The same applies to the constraint on `Edge`, and the same type
+parameters and constraints are repeated for the function `New`.
+We aren't claiming that this is simple, but we are claiming that it is
+possible.
+
+It's worth noting that while at first glance this may look like a
+typical use of interface types, `Node` and `Edge` are non-interface
+types with specific methods.
+In order to use `graph.Graph`, the type arguments used for `Node` and
+`Edge` have to define methods that follow a certain pattern, but they
+don't have to actually use interface types to do so.
+In particular, the methods do not return interface types.
+
+For example, consider these type definitions in some other package:
+
+```Go
+// Vertex is a node in a graph.
+type Vertex struct { ... }
+
+// Edges returns the edges connected to v.
+type (v *Vertex) Edges() []*FromTo { ... }
+
+// FromTo is an edge in a graph.
+type FromTo struct { ... }
+
+// Nodes returns the nodes that ft connects.
+func (ft *FromTo) Nodes() (*Vertex, *Vertex) { ... }
+```
+
+There are no interface types here, but we can instantiate
+`graph.Graph` using the type arguments `*Vertex` and `*FromTo`.
+
+```Go
+var g = graph.New(*Vertex, *FromTo)([]*Vertex{ ... })
+```
+
+`*Vertex` and `*FromTo` are not interface types, but when used
+together they define methods that implement the constraints of
+`graph.Graph`.
+Note that we couldn't pass plain `Vertex` or `FromTo` to `graph.New`,
+since `Vertex` and `FromTo` do not implement the constraints.
+The `Edges` and `Nodes` methods are defined on the pointer types
+`*Vertex` and `*FromTo`; the types `Vertex` and `FromTo` do not have
+any methods.
+
+When we use a generic interface type as a constraint, we first
+instantiate the type with the type argument(s) supplied in the type
+parameter list, and then compare the corresponding type argument
+against the instantiated constraint.
+In this example, the `Node` type argument to `graph.New` has a
+constraint `NodeConstraint(Edge)`.
+When we call `graph.New` with a `Node` type argument of `*Vertex` and
+a `Edge` type argument of `*FromTo`, in order to check the constraint
+on `Node` the compiler instantiates `NodeConstraint` with the type
+argument `*FromTo`.
+That produces an instantiated constraint, in this case a requirement
+that `Node` have a method `Edges() []*FromTo`, and the compiler
+verifies that `*Vertex` satisfies that constraint.
+
+Although `Node` and `Edge` do not have to be instantiated with
+interface types, it is also OK to use interface types if you like.
+
+```Go
+type NodeInterface interface { Edges() []EdgeInterface }
+type EdgeInterface interface { Nodes() (NodeInterface, NodeInterface) }
+```
+
+We could instantiate `graph.Graph` with the types `NodeInterface` and
+`EdgeInterface`, since they implement the type constraints.
+There isn't much reason to instantiate a type this way, but it is
+permitted.
+
+This ability for type parameters to refer to other type parameters
+illustrates an important point: it should be a requirement for any
+attempt to add generics to Go that it be possible to instantiate
+generic code with multiple type arguments that refer to each other in
+ways that the compiler can check.
+
+### Pointer methods
+
+There are cases where a generic function will only work as expected if
+a type argument `A` has methods defined on the pointer type `*A`.
+This happens when writing a generic function that expects to call a
+method that modifies a value.
+
+Consider this example of a function that expects a type `T` that has a
+`Set(string)` method that initializes the value based on a string.
+
+```Go
+// Setter is a type constraint that requires that the type
+// implement a Set method that sets the value from a string.
+type Setter interface {
+	Set(string)
+}
+
+// FromStrings takes a slice of strings and returns a slice of T,
+// calling the Set method to set each returned value.
+//
+// Note that because T is only used for a result parameter,
+// type inference does not work when calling this function.
+// The type argument must be passed explicitly at the call site.
+//
+// This example compiles but is unlikely to work as desired.
+func FromStrings(type T Setter)(s []string) []T) {
+	result := make([]T, len(s))
+	for i, v := range s {
+		result[i].Set(v)
+	}
+	return result
+}
+```
+
+Now let's see some code in a different package (this example is
+invalid).
+
+```Go
+// Settable is a integer type that can be set from a string.
+type Settable int
+
+// Set sets the value of *p from a string.
+func (p *Settable) Set(s string) {
+	i, _ := strconv.Atoi(s) // real code should not ignore the error
+	*p = Settable(i)
+}
+
+func F() {
+	// INVALID
+	nums := FromStrings(Settable)([]string{"1", "2"})
+	// Here we want nums to be []Settable{1, 2}.
+	...
+}
+```
+
+The goal is to use `FromStrings` to get a slice of type `[]Settable`.
+Unfortunately, this example is not valid and will not compile.
+
+The problem is that `FromStrings` requires a type that has a
+`Set(string)` method.
+The function `F` is trying to instantiate `FromStrings` with
+`Settable`, but `Settable` does not have a `Set` method.
+The type that has a `Set` method is `*Settable`.
+
+So let's rewrite `F` to use `*Settable` instead.
+
+```Go
+func F() {
+	// Compiles but does not work as desired.
+	// This will panic at run time when calling the Set method.
+	nums := FromStrings(*Settable)([]string{"1", "2"})
+	...
+}
+```
+
+This compiles but unfortunately it will panic at run time.
+The problem is that `FromStrings` creates a slice of type `[]T`.
+When instantiated with `*Settable`, that means a slice of type
+`[]*Settable`.
+When `FromStrings` calls `result[i].Set(v)`, that passes the pointer
+stored in `result[i]` to the `Set` method.
+That pointer is `nil`.
+The `Settable.Set` method will be invoked with a `nil` receiver,
+and will raise a panic due to a `nil` dereference error.
+
+What we need is a way to write `FromStrings` such that it can take
+the type `Settable` as an argument but invoke a pointer method.
+To repeat, we can't use `Settable` because it doesn't have a `Set`
+method, and we can't use `*Settable` because then we can't create a
+slice of type `Settable`.
+
+One approach that could work would be to use two different type
+parameters: both `Settable` and `*Settable`.
+
+```Go
+package from
+
+// Setter2 is a type constraint that requires that the type
+// implement a Set method that sets the value from a string,
+// and also requires that the type be a pointer to its type parameter.
+type Setter2(type B) interface {
+	Set(string)
+	type *B
+}
+
+// FromStrings2 takes a slice of strings and returns a slice of T,
+// calling the Set method to set each returned value.
+//
+// We use two different type parameters so that we can return
+// a slice of type T but call methods on *T.
+// The Setter2 constraint ensures that PT is a pointer to T.
+func FromStrings2(type T interface{}, PT Setter2(T))(s []string) []T {
+	result := make([]T, len(s))
+	for i, v := range s {
+		// The type of &result[i] is *T which is in the type list
+		// of Setter2, so we can convert it to PT.
+		p := PT(&result[i])
+		// PT has a Set method.
+		p.Set(v)
+	}
+	return result
+}
+```
+
+We would call `FromStrings2` like this:
+
+```Go
+func F2() {
+	// FromStrings2 takes two type parameters.
+	// The second parameter must be a pointer to the first.
+	// Settable is as above.
+	nums := FromStrings2(Settable, *Settable)([]string{"1", "2"})
+	// Now nums is []Settable{1, 2}.
+	...
+}
+```
+
+This approach works as expected, but it is awkward.
+It forces `F2` to work around a problem in `FromStrings2` by passing
+two type arguments.
+The second type argument is required to be a pointer to the first type
+argument.
+This is a complex requirement for what seems like it ought to be a
+reasonably simple case.
+
+Another approach would be to pass in a function rather than calling a
+method.
+
+```Go
+// FromStrings3 takes a slice of strings and returns a slice of T,
+// calling the set function to set each returned value.
+func FromStrings3(type T)(s []string, set func(*T, string)) []T {
+	results := make([]T, len(s))
+	for i, v := range s {
+		set(&results[i], v)
+	}
+	return results
+}
+```
+
+We would call `Strings3` like this:
+
+```Go
+func F3() {
+	// FromStrings3 takes a function to set the value.
+	// Settable is as above.
+	nums := FromStrings3(Settable)([]string{"1", "2"},
+		func(p *Settable, s string) { p.Set(s) })
+	// Now nums is []Settable{1, 2}.
+}
+```
+
+This approach also works as expected, but it is also awkward.
+The caller has to pass in a function just to call the `Set` method.
+This is the kind of boilerplate code that we would hope to avoid when
+using generics.
+
+Although these approaches are awkward, they do work.
+That said, we suggest another feature to address this kind of issue: a
+way to express constraints on the pointer to the type parameter,
+rather than on the type parameter itself.
+The way to do this is to write the type parameter as though it were a
+pointer type: `(type *T Constraint)`.
+
+Writing `*T` instead of `T` in a type parameter list changes two
+things.
+Let's assume that the type argument at the call site is `A`, and the
+constraint is `Constraint` (this syntax may be used without a
+constraint, but there is no reason to do so).
+
+The first thing that changes is that `Constraint` is applied to `*A`
+rather than `A`.
+That is, `*A` must implement `Constraint`.
+It's OK if `A` implements `Constraint`, but the requirement is that
+`*A` implement it.
+Note that if `Constraint` has any methods, this implies that `A` must
+not be a pointer type: if `A` is a pointer type, then `*A` is a
+pointer to a pointer, and such types never have any methods.
+
+The second thing that changes is that within the body of the function,
+any methods in `Constraint` are treated as though they were pointer
+methods.
+They may only be invoked on values of type `*T` or addressable values
+of type `T`.
+
+```Go
+// FromStrings takes a slice of strings and returns a slice of T,
+// calling the Set method to set each returned value.
+//
+// We write *T, meaning that given a type argument A,
+// the pointer type *A must implement Setter.
+//
+// Note that because T is only used for a result parameter,
+// type inference does not work when calling this function.
+// The type argument must be passed explicitly at the call site.
+func FromStrings(type *T Setter)(s []string) []T {
+	result := make([]T, len(s))
+	for i, v := range s {
+		// result[i] is an addressable value of type T,
+		// so it's OK to call Set.
+		result[i].Set(v)
+	}
+	return result
+}
+```
+
+Again, using `*T` here means that given a type argument `A`, the type
+`*A` must implement the constraint `Setter`.
+In this case, `Set` must be in the method set of `*A`.
+Within `FromStrings`, using `*T` means that the `Set` method may only
+be called on an addressable value of type `T`.
+
+We can now use this as
+
+```Go
+func F() {
+	// With the rewritten FromStrings, this is now OK.
+	// *Settable implements Setter.
+	nums := from.Strings(Settable)([]string{"1", "2"})
+	// Here nums is []Settable{1, 2}.
+	...
+}
+```
+
+To be clear, using `type *T Setter` does not mean that the `Set`
+method must only be a pointer method.
+`Set` could still be a value method.
+That would be OK because all value methods are also in the pointer
+type's method set.
+In this example that only makes sense if `Set` can be written as a
+value method, which might be the case when defining the method on a
+struct that contains pointer fields.
+
+### Using generic types as unnamed function parameter types
+
+When parsing an instantiated type as an unnamed function parameter
+type, there is a parsing ambiguity.
+
+```Go
+var f func(x(T))
+```
+
+In this example we don't know whether the function has a single
+unnamed parameter of the instantiated type `x(T)`, or whether this is
+a named parameter `x` of the type `(T)` (written with parentheses).
+
+We would prefer that this mean the former: an unnamed parameter of the
+instantiated type `x(T)`.
+This is not actually backward compatible with the current language,
+where it means the latter.
+However, the gofmt program currently rewrites `func(x(T))` to `func(x
+T)`, so `func(x(T))` is very unusual in plain Go code.
+
+Therefore, we propose that the language change so that `func(x(T))`
+now means a single parameter of type `x(T)`.
+This will potentially break some existing programs, but the fix will
+be to simply run gofmt.
+This will potentially change the meaning of programs that write
+`func(x(T))`, that don't use gofmt, and that choose to introduce a
+generic type `x` with the same name as a function parameter with a
+parenthesized type.
+We believe that such programs will be exceedingly rare.
+
+Still, this is a risk, and if the risk seems too large we can avoid
+making this change.
+
+### Values of type parameters are not boxed
+
+In the current implementations of Go, interface values always hold
+pointers.
+Putting a non-pointer value in an interface variable causes the value
+to be _boxed_.
+That means that the actual value is stored somewhere else, on the heap
+or stack, and the interface value holds a pointer to that location.
+
+In this design, values of generic types are not boxed.
+For example, let's look back at our earlier example of
+`from.Strings`.
+When it is instantiated with type `Settable`, it returns a value of
+type `[]Settable`.
+For example, we can write
+
+```Go
+// Settable is an integer type that can be set from a string.
+type Settable int
+
+// Set sets the value of *p from a string.
+func (p *Settable) Set(s string) (err error) {
+	// same as above
+}
+
+func F() {
+	// The type of nums is []Settable.
+	nums, err := from.Strings(Settable)([]string{"1", "2"})
+	if err != nil { ... }
+	// Settable can be converted directly to int.
+	// This will set first to 1.
+	first := int(nums[0])
+	...
+}
+```
+
+When we call `from.Strings` with the type `Settable` we get back a
+`[]Settable` (and an error).
+The elements of that slice will be `Settable` values, which is to say,
+they will be integers.
+They will not be boxed, even though they were created and set by a
+generic function.
+
+Similarly, when a generic type is instantiated it will have the
+expected types as components.
+
+```Go
+type Pair(type F1, F2) struct {
+	first  F1
+	second F2
+}
+```
+
+When this is instantiated, the fields will not be boxed, and no
+unexpected memory allocations will occur.
+The type `Pair(int, string)` is convertible to `struct { first int;
+second string }`.
+
+### More on type lists
+
+Let's return now to type lists to cover some less important details
+that are still worth noting.
+These are not additional rules or concepts, but are consequences of
+how type lists work.
+
+#### Both type lists and methods in constraints
+
+A constraint may use both type lists and methods.
+
+```Go
+// StringableSignedInteger is a type constraint that matches any
+// type that is both 1) defined as a signed integer type;
+// 2) has a String method.
+type StringableSignedInteger interface {
+	type int, int8, int16, int32, int64
+	String() string
+}
+```
+
+This constraint permits any type whose underlying type is one of the
+listed types, provided it also has a `String() string` method.
+It's worth noting that although the `StringableSignedInteger`
+constraint explicitly lists `int`, the type `int` will not itself be
+permitted as a type argument, since `int` does not have a `String`
+method.
+An example of a type argument that would be permitted is `MyInt`,
+defined as:
+
+```Go
+// MyInt is a stringable int.
+type MyInt int
+
+// The String method returns a string representation of mi.
+func (mi MyInt) String() string {
+	return fmt.Sprintf("MyInt(%d)", mi)
+}
+```
+
+#### Composite types in constraints
+
+A type in a constraint may be a type literal.
+
+```Go
+type byteseq interface {
+	type string, []byte
+}
+```
+
+The usual rules apply: the type argument for this constraint may be
+`string` or `[]byte` or a type defined as one of those types; a
+generic function with this constraint may use any operation permitted
+by both `string` and `[]byte`.
+
+The `byteseq` constraint permits writing generic functions that work
+for either `string` or `[]byte` types.
+
+```Go
+// Join concatenates the elements of its first argument to create a
+// single value. sep is placed between elements in the result.
+// Join works for string and []byte types.
+func Join(type T byteseq)(a []T, sep T) (ret T) {
+	if len(a) == 0 {
+		// Use the result parameter as a zero value;
+		// see discussion of zero value in the Issues section.
+		return ret
+	}
+	if len(a) == 1 {
+		// We know that a[0] is either a string or a []byte.
+		// We can append either a string or a []byte to a []byte,
+		// producing a []byte. We can convert that []byte to
+		// either a []byte (a no-op conversion) or a string.
+		return T(append([]byte(nil), a[0]...))
+	}
+	// We can call len on sep because we can call len
+	// on both string and []byte.
+	n := len(sep) * (len(a) - 1)
+	for _, v := range a {
+		// Another case where we call len on string or []byte.
+		n += len(v)
+	}
+
+	b := make([]byte, n)
+	// We can call copy to a []byte with an argument of
+	// either string or []byte.
+	bp := copy(b, a[0])
+	for _, s := range a[1:] {
+		bp += copy(b[bp:], sep)
+		bp += copy(b[bp:], s)
+	}
+	// As above, we can convert b to either []byte or string.
+	return T(b)
+}
+```
+
+#### Type parameters in type lists
+
+A type literal in a constraint can refer to type parameters of the
+constraint.
+In this example, the generic function `Map` takes two type parameters.
+The first type parameter is required to have an underlying type that
+is a slice of the second type parameter.
+There are no constraints on the second slice parameter.
+
+```Go
+// SliceConstraint is a type constraint that matches a slice of
+// the type parameter.
+type SliceConstraint(type T) interface {
+	type []T
+}
+
+// Map takes a slice of some element type and a transformation function,
+// and returns a slice of the function applied to each element.
+// Map returns a slice that is the same type as its slice argument,
+// even if that is a defined type.
+func Map(type S SliceConstraint(E), E interface{})(s S, f func(E) E) S {
+	r := make(S, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// MySlice is a simple defined type.
+type MySlice []int
+
+// DoubleMySlice takes a value of type MySlice and returns a new
+// MySlice value with each element doubled in value.
+func DoubleMySlice(s MySlice) MySlice {
+	v := Map(MySlice, int)(s, func(e int) int { return 2 * e })
+	// Here v has type MySlice, not type []int.
+	return v
+}
+```
+
+#### Type conversions
+
+In a function with two type parameters `From` and `To`, a value of
+type `From` may be converted to a value of type `To` if all the
+types accepted by `From`'s constraint can be converted to all the
+types accepted by `To`'s constraint.
+If either type parameter does not accept types, then type conversions
+are not permitted.
+
+This is a consequence of the general rule that a generic function may
+use any operation that is permitted by all types listed in the type
+list.
+
+For example:
+
+```Go
+type integer interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr
+}
+
+func Convert(type To, From integer)(from From) To {
+	to := To(from)
+	if From(to) != from {
+		panic("conversion out of range")
+	}
+	return to
+}
+```
+
+The type conversions in `Convert` are permitted because Go permits
+every integer type to be converted to every other integer type.
+
+#### Untyped constants
+
+Some functions use untyped constants.
+An untyped constant is permitted with a value of some type parameter
+if it is permitted with every type accepted by the type parameter's
+constraint.
+
+As with type conversions, this is a consequence of the general rule
+that a generic function may use any operation that is permitted by all
+types listed in the type list.
+
+```Go
+type integer interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr
+}
+
+func Add10(type T integer)(s []T) {
+	for i, v := range s {
+		s[i] = v + 10 // OK: 10 can convert to any integer type
+	}
+}
+
+// This function is INVALID.
+func Add1024(type T integer)(s []T) {
+	for i, v := range s {
+		s[i] = v + 1024 // INVALID: 1024 not permitted by int8/uint8
+	}
+}
+```
+
+#### Notes on composite types in type lists
+
+It's not clear that we fully understand the use of composite types in
+type lists.
+For example, consider
+
+```Go
+type structField interface {
+	type struct { a int; x int },
+		struct { b int; x float64 },
+		struct { c int; x uint64 }
+}
+
+func IncrementX(type T structField)(p *T) {
+	v := p.x
+	v++
+	p.x = v
+}
+```
+
+This constraint on the type parameter of `IncrementX` is such that
+every valid type argument is a struct with a field `x` of some numeric
+type.
+Therefore, it is tempting to say that `IncrementX` is a valid
+function.
+This would mean that the type of `v` is a type based on a type
+parameter, with an implicit constraint of `interface { type int,
+float64, uint64 }`.
+This could get fairly complex, and there may be details here that we
+don't understand.
+
+The initial implementation may not support composite types in type
+lists at all, although that would make the `Join` example shown
+earlier invalid.
+
+#### Type lists in embedded constraints
+
+When a constraint embeds another constraint, the type list of the
+final constraint is the intersection of all the type lists involved.
+If there are multiple embedded types, intersection preserves the
+property that any  type argument must satisfy the requirements of all
+embedded types.
+
+```Go
+// Addable is types that support the + operator.
+type Addable interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64, complex64, complex128,
+		string
+}
+
+// Byteseq is a byte sequence: either string or []byte.
+type Byteseq interface {
+	type string, []byte
+}
+
+// AddableByteseq is a byte sequence that supports +.
+// This is every type is that is both Addable and Byteseq.
+// In other words, just the type string.
+type AddableByteseq interface {
+	Addable
+	Byteseq
+}
+```
+
+#### General notes on type lists
+
+It may seem awkward to explicitly list types in a constraint, but it
+is clear both as to which type arguments are permitted at the call
+site, and which operations are permitted by the generic function.
+
+If the language later changes to support operator methods (there are
+no such plans at present), then constraints will handle them as they
+do any other kind of method.
+
+There will always be a limited number of predeclared types, and a
+limited number of operators that those types support.
+Future language changes will not fundamentally change those facts, so
+this approach will continue to be useful.
+
+This approach does not attempt to handle every possible operator.
+It's not clear that it works well for composite types.
+The expectation is that those will be handled using composite types in
+generic function and type declarations, rather than requiring
+composite types as a type argument.
+For example, we expect functions that want to index into a slice to be
+parameterized on the slice element type `T`, and to use parameters or
+variables of type `[]T`.
+
+As shown in the `DoubleMySlice` example above, this approach makes it
+awkward to declare generic functions that accept and return a
+composite type and want to return the same result type as their
+argument type.
+Defined composite types are not common, but they do arise.
+This awkwardness is a weakness of this approach.
+
+### Reflection
+
+We do not propose to change the reflect package in any way.
+When a type or function is instantiated, all of the type parameters
+will become ordinary non-generic types.
+The `String` method of a `reflect.Type` value of an instantiated type
+will return the name with the type arguments in parentheses.
+For example, `List(int)`.
+
+It's impossible for non-generic code to refer to generic code without
+instantiating it, so there is no reflection information for
+uninstantiated generic types or functions.
+
+### Implementation
+
+Russ Cox [famously observed](https://research.swtch.com/generic) that
+generics require choosing among slow programmers, slow compilers, or
+slow execution times.
+
+We believe that this design permits different implementation choices.
+Code may be compiled separately for each set of type arguments, or it
+may be compiled as though each type argument is handled similarly to
+an interface type with method calls, or there may be some combination
+of the two.
+
+In other words, this design permits people to stop choosing slow
+programmers, and permits the implementation to decide between slow
+compilers (compile each set of type arguments separately) or slow
+execution times (use method calls for each operation on a value of a
+type argument).
+
+### Summary
+
+While this document is long and detailed, the actual design reduces to
+a few major points.
+
+* Functions and types can have type parameters, which are defined
+  using optional constraints, which are interface types.
+* Constraints describe the methods required and the types permitted
+  for a type argument.
+* Constraints describe the methods and operations permitted for a type
+  parameter.
+* Type inference will often permit omitting type arguments when
+  calling functions with type parameters.
+
+This design is completely backward compatible, except for a suggested
+change in the meaning of `func F(x(T))`.
+
+We believe that this design addresses people's needs for generic
+programming in Go, without making the language any more complex than
+necessary.
+
+We can't truly know the impact on the language without years of
+experience with this design.
+That said, here are some speculations.
+
+#### Complexity
+
+One of the great aspects of Go is its simplicity.
+Clearly this design makes the language more complex.
+
+We believe that the increased complexity is small for people reading
+well written generic code, rather than writing it.
+Naturally people must learn the new syntax for declaring type
+parameters.
+This new syntax, and the new support for type lists in interfaces, are
+the only new syntactic constructs in this design.
+The code within a generic function reads like ordinary Go code, as can
+be seen in the examples below.
+It is an easy shift to go from `[]int` to `[]T`.
+Type parameter constraints serve effectively as documentation,
+describing the type.
+
+We expect that most packages will not define generic types or
+functions, but many packages are likely to use generic types or
+functions defined elsewhere.
+In the common case, generic functions work exactly like non-generic
+functions: you simply call them.
+Type inference means that you do not have to write out the type
+arguments explicitly.
+The type inference rules are designed to be unsurprising: either the
+type arguments are deduced correctly, or the call fails and requires
+explicit type parameters.
+Type inference uses type identity, with no attempt to resolve two
+types that are similar but not identical, which removes significant
+complexity.
+
+Packages using generic types will have to pass explicit type
+arguments.
+The syntax for this is familiar.
+The only change is passing arguments to types rather than only to
+functions.
+
+In general, we have tried to avoid surprises in the design.
+Only time will tell whether we succeeded.
+
+#### Pervasiveness
+
+We expect that a few new packages will be added to the standard
+library.
+A new `slices` packages will be similar to the existing bytes and
+strings packages, operating on slices of any element type.
+New `maps` and `chans` packages will provide simple algorithms that
+are currently duplicated for each element type.
+A `set` package may be added.
+
+A new `constraints` package will provide standard constraints, such as
+constraints that permit all integer types or all numeric types.
+
+Packages like `container/list` and `container/ring`, and types like
+`sync.Map` and `sync/atomic.Value`, will be updated to be compile-time
+type-safe, either using new names or new versions of the packages.
+
+The `math` package will be extended to provide a set of simple
+standard algorithms for all numeric types, such as the ever popular
+`Min` and `Max` functions.
+
+We may add generic variants to the `sort` package.
+
+It is likely that new special purpose compile-time type-safe container
+types will be developed.
+
+We do not expect approaches like the C++ STL iterator types to become
+widely used.
+In Go that sort of idea is more naturally expressed using an interface
+type.
+In C++ terms, using an interface type for an iterator can be seen as
+carrying an abstraction penalty, in that run-time efficiency will be
+less than C++ approaches that in effect inline all code; we believe
+that Go programmers will continue to find that sort of penalty to be
+acceptable.
+
+As we get more container types, we may develop a standard `Iterator`
+interface.
+That may in turn lead to pressure to modify the language to add some
+mechanism for using an `Iterator` with the `range` clause.
+That is very speculative, though.
+
+#### Efficiency
+
+It is not clear what sort of efficiency people expect from generic
+code.
+
+Generic functions, rather than generic types, can probably be compiled
+using an interface-based approach.
+That will optimize compile time, in that the function is only compiled
+once, but there will be some run time cost.
+
+Generic types may most naturally be compiled multiple times for each
+set of type arguments.
+This will clearly carry a compile time cost, but there shouldn't be
+any run time cost.
+Compilers can also choose to implement generic types similarly to
+interface types, using special purpose methods to access each element
+that depends on a type parameter.
+
+Only experience will show what people expect in this area.
+
+#### Omissions
+
+We believe that this design covers the basic requirements for
+generic programming.
+However, there are a number of programming constructs that are not
+supported.
+
+* No specialization.
+  There is no way to write multiple versions of a generic function
+  that are designed to work with specific type arguments.
+* No metaprogramming.
+  There is no way to write code that is executed at compile time to
+  generate code to be executed at run time.
+* No higher level abstraction.
+  There is no way to speak about a function with type arguments other
+  than to call it or instantiate it.
+  There is no way to speak about a generic type other than to
+  instantiate it.
+* No general type description.
+  In order to use operators in a generic function, constraints list
+  specific types, rather than describing the characteristics that a
+  type must have.
+  This is easy to understand but may be limiting at times.
+* No covariance or contravariance of function parameters.
+* No operator methods.
+  You can write a generic container that is compile-time type-safe,
+  but you can only access it with ordinary methods, not with syntax
+  like `c[k]`.
+* No currying.
+  There is no way to specify only some of the type arguments, other
+  than by using a helper function or a wrapper type.
+* No variadic type parameters.
+  There is no support for variadic type parameters, which would permit
+  writing a single generic function that takes different numbers of
+  both type parameters and regular parameters.
+* No adaptors.
+  There is no way for a constraint to define adaptors that could be
+  used to support type arguments that do not already implement the
+  constraint, such as, for example, defining an `==` operator in terms
+  of an `Equal` method, or vice-versa.
+* No parameterization on non-type values such as constants.
+  This arises most obviously for arrays, where it might sometimes be
+  convenient to write `type Matrix(type n int) [n][n]float64`.
+  It might also sometimes be useful to specify significant values for
+  a container type, such as a default value for elements.
+
+#### Issues
+
+There are some issues with this design that deserve a more detailed
+discussion.
+We think these issues are relatively minor compared to the design as a
+whole, but they still deserve a complete hearing and discussion.
+
+##### The zero value
+
+This design has no simple expression for the zero value of a type
+parameter.
+For example, consider this implementation of optional values that uses
+pointers:
+
+```Go
+type Optional(type T) struct {
+	p *T
+}
+
+func (o Optional(T)) Val() T {
+	if o.p != nil {
+		return *o.p
+	}
+	var zero T
+	return zero
+}
+```
+
+In the case where `o.p == nil`, we want to return the zero value of
+`T`, but we have no way to write that.
+It would be nice to be able to write `return nil`, but that wouldn't
+work if `T` is, say, `int`; in that case we would have to write
+`return 0`.
+And, of course, there is no way to write a constraint to support
+either `return nil` or `return 0`.
+
+Some approaches to this are:
+
+* Use `var zero T`, as above, which works with the existing design
+  but requires an extra statement.
+* Use `*new(T)`, which is cryptic but works with the existing
+  design.
+* For results only, name the result parameter `_`, and use a naked
+  `return` statement to return the zero value.
+* Extend the design to permit using `nil` as the zero value of any
+  generic type (but see [issue 22729](https://golang.org/issue/22729)).
+* Extend the design to permit using `T{}`, where `T` is a type
+  parameter, to indicate the zero value of the type.
+* Change the language to permit using `_` on the right hand of an
+  assignment (including `return` or a function call) as proposed in
+  [issue 19642](https://golang.org/issue/19642).
+* Change the language to permit `return ...` to return zero values of
+  the result types, as proposed in
+  [issue 21182](https://golang.org/issue/21182).
+
+We feel that more experience with this design is needed before
+deciding what, if anything, to do here.
+
+##### Lots of Irritating Silly Parentheses
+
+Calling a function with type parameters requires an additional list of
+type arguments if the type arguments can not be inferred.
+If the function returns a function, and we call that, we get still
+more parentheses.
+
+```Go
+	F(int, float64)(x, y)(s)
+```
+
+We experimented with other syntaxes, such as using a colon to separate
+the type arguments from the regular arguments.
+The current design seems to us to be the nicest, but perhaps something
+better is possible.
+
+##### Defined composite types
+
+As [discussed above](#Type parameters in type lists), an extra type
+parameter is required for a function to take, as an argument, a
+defined type whose underlying type is a composite type, and to return
+the same defined type as a result.
+
+For example, this function will map a function across a slice.
+
+```Go
+// Map applies f to each element of s, returning a new slice
+// holding the results.
+func Map(type T)(s []T, f func(T) T) []T {
+	r := make([]T, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+```
+
+However, when called on a defined type, it will return a slice of the
+element type of that type, rather than the defined type itself.
+
+```Go
+// MySlice is a defined type.
+type MySlice []int
+
+// DoubleMySlice returns a new MySlice whose elements are twice
+// that of the corresponding elements of s.
+func DoubleMySlice(s MySlice) MySlice {
+	s2 := Map(s, func(e int) int { return 2 * e })
+	// Here s2 is type []int, not type MySlice.
+	return MySlice(s2)
+}
+```
+
+As [discussed above](#Type parameters in type lists), this can be
+avoided by using an extra type parameter for `Map`, and using
+constraints that describe the required relationship between the slice
+and element types.
+This works but is awkward.
+
+##### Identifying the matched predeclared type
+
+The design doesn't provide any way to test the underlying type matched
+by a type argument.
+Code can test the actual type argument through the somewhat awkward
+approach of converting to an empty interface type and using a type
+assertion or a type switch.
+But that lets code test the actual type argument, which is not the
+same as the underlying type.
+
+Here is an example that shows the difference.
+
+```Go
+type Float interface {
+	type float32, float64
+}
+
+func NewtonSqrt(type T Float)(v T) T {
+	var iterations int
+	switch (interface{})(v).(type) {
+	case float32:
+		iterations = 4
+	case float64:
+		iterations = 5
+	default:
+		panic(fmt.Sprintf("unexpected type %T", v))
+	}
+	// Code omitted.
+}
+
+type MyFloat float32
+
+var G = NewtonSqrt(MyFloat(64))
+```
+
+This code will panic when initializing `G`, because the type of `v` in
+the `NewtonSqrt` function will be `MyFloat`, not `float32` or
+`float64`.
+What this function actually wants to test is not the type of `v`, but
+the type that `v` matched in the constraint.
+
+One way to handle this would be to permit type switches on the type
+`T`, with the proviso that the type `T` would always match a type
+defined in the constraint.
+This kind of type switch would only be permitted if the constraint
+lists explicit types, and only types listed in the constraint would be
+permitted as cases.
+
+##### No way to express convertability
+
+The design has no way to express convertability between two different
+type parameters.
+For example, there is no way to write this function:
+
+```Go
+// Copy copies values from src to dst, converting them as they go.
+// It returns the number of items copied, which is the minimum of
+// the lengths of dst and src.
+// This implementation is INVALID.
+func Copy(type T1, T2)(dst []T1, src []T2) int {
+	for i, x := range src {
+		if i > len(dst) {
+			return i
+		}
+		dst[i] = T1(x) // INVALID
+	}
+	return len(src)
+}
+```
+
+The conversion from type `T2` to type `T1` is invalid, as there is no
+constraint on either type that permits the conversion.
+Worse, there is no way to write such a constraint in general.
+In the particular case that both `T1` and `T2` can require some type
+list, then this function can be written as described earlier when
+discussing [type conversions using type lists](#Type conversions).
+But, for example, there is no way to write a constraint for the case
+in which `T1` is an interface type and `T2` is a type that implements
+that interface.
+
+It's worth noting that if `T1` is an interface type then this can be
+written using a conversion to the empty interface type and a type
+assertion, but this is, of course, not compile-time type-safe.
+
+```Go
+// Copy copies values from src to dst, converting them as they go.
+// It returns the number of items copied, which is the minimum of
+// the lengths of dst and src.
+func Copy(type T1, T2)(dst []T1, src []T2) int {
+	for i, x := range src {
+		if i > len(dst) {
+			return i
+		}
+		dst[i] = (interface{})(x).(T1)
+	}
+	return len(src)
+}
+```
+
+#### Discarded ideas
+
+This design is not perfect, and it will be further refined as we gain
+experience with it.
+That said, there are many ideas that we've already considered in
+detail.
+This section lists some of those ideas in the hopes that it will help
+to reduce repetitive discussion.
+The ideas are presented in the form of a FAQ.
+
+##### What happened to contracts?
+
+An earlier draft design of generics implemented constraints using a
+new language construct called contracts.
+Type lists appeared only in contracts, rather than on interface
+types.
+However, many people had a hard time understanding the difference
+between contracts and interface types.
+It also turned out that contracts could be represented as a set of
+corresponding interfaces; thus there was no loss in expressive power
+without contracts.
+We decided to simplify the approach to use only interface types.
+
+##### Why not use methods instead of type lists?
+
+_Type lists are weird._
+_Why not write methods for all operators?_
+
+It is possible to permit operator tokens as method names, leading to
+methods such as `+(T) T`.
+Unfortunately, that is not sufficient.
+We would need some mechanism to describe a type that matches any
+integer type, for operations such as shifts `<<(integer) T` and
+indexing `[](integer) T` which are not restricted to a single int
+type.
+We would need an untyped boolean type for operations such as `==(T)
+untyped bool`.
+We would need to introduce new notation for operations such as
+conversions, or to express that one may range over a type, which would
+likely require some new syntax.
+We would need some mechanism to describe valid values of untyped
+constants.
+We would have to consider whether support for `<(T) bool` means that a
+generic function can also use `<=`, and similarly whether support for
+`+(T) T` means that a function can also use `++`.
+It might be possible to make this approach work but it's not
+straightforward.
+The approach used in this design seems simpler and relies on only one
+new syntactic construct (type lists) and one new name (`comparable`).
+
+##### Why not put type parameters on packages?
+
+We investigated this extensively.
+It becomes problematic when you want to write a `list` package, and
+you want that package to include a `Transform` function that converts
+a `List` of one element type to a `List` of another element type.
+It's very awkward for a function in one instantiation of a package to
+return a type that requires a different instantiation of the same
+package.
+
+It also confuses package boundaries with type definitions.
+There is no particular reason to think that the uses of generic types
+will break down neatly into packages.
+Sometimes they will, sometimes they won't.
+
+##### Why not use the syntax `F<T>` like C++ and Java?
+
+When parsing code within a function, such as `v := F<T>`, at the point
+of seeing the `<` it's ambiguous whether we are seeing a type
+instantiation or an expression using the `<` operator.
+Resolving that requires effectively unbounded lookahead.
+In general we strive to keep the Go parser efficient.
+
+##### Why not use the syntax `F[T]`?
+
+When parsing a type declaration `type A [T] int` it's ambiguous
+whether this is a generic type defined (uselessly) as `int` or whether
+it is an array type with `T` elements.
+However, this could be addressed by requiring `type A [type T] int`
+for a generic type.
+
+Parsing declarations like `func f(A[T]int)` (a single parameter of
+type `[T]int`) and `func f(A[T], int)` (two parameters, one of type
+`A[T]` and one of type `int`) show that some additional parsing
+lookahead is required.
+This is solvable but adds parsing complexity.
+
+The language generally permits a trailing comma in a comma-separated
+list, so `A[T,]` should be permitted if `A` is a generic type, but
+normally would not be permitted for an index expression.
+However, the parser can't know whether `A` is a generic type or a
+value of slice, array, or map type, so this parse error can not be
+reported until after type checking is complete.
+Again, solvable but complicated.
+
+More generally, we felt that the square brackets were too intrusive on
+the page and that parentheses were more Go like.
+We will reevaluate this decision as we gain more experience.
+
+##### Why not use `F«T»`?
+
+We considered it but we couldn't bring ourselves to require
+non-ASCII.
+
+##### Why not define constraints in a builtin package?
+
+_Instead of writing out type lists, use names like_
+_`constraints.Arithmetic` and `constraints.Comparable`._
+
+Listing all the possible combinations of types gets rather lengthy.
+It also introduces a new set of names that not only the writer of
+generic code, but, more importantly, the reader, must remember.
+One of the driving goals of this design is to introduce as few new
+names as possible.
+In this design we introduce only one new predeclared name.
+
+We expect that if people find such names useful, we can introduce a
+package `constraints` that defines the useful names in the form of
+constraints that can be used by other types and functions and embedded
+in other constraints.
+That will define the most useful names in the standard library while
+giving programmers the flexibility to use other combinations of types
+where appropriate.
+
+##### Why not permit type assertions on values whose type is a type parameter?
+
+In an earlier version of this design, we permitted using type
+assertions and type switches on variables whose type was a type
+parameter, or whose type was based on a type parameter.
+We removed this facility because it is always possible to convert a
+value of any type to the empty interface type, and then use a type
+assertion or type switch on that.
+Also, it was sometimes confusing that in a constraint with a type
+list, a type assertion or type switch would use the actual type
+argument, not the underlying type of the type argument (the difference
+is explained in the section on [identifying the matched predeclared
+type](#Identifying the matched predeclared type)).
+
+#### Comparison with Java
+
+Most complaints about Java generics center around type erasure.
+This design does not have type erasure.
+The reflection information for a generic type will include the full
+compile-time type information.
+
+In Java type wildcards (`List<? extends Number>`, `List<? super
+Number>`) implement covariance and contravariance.
+These concepts are missing from Go, which makes generic types much
+simpler.
+
+#### Comparison with C++
+
+C++ templates do not enforce any constraints on the type arguments
+(unless the concept proposal is adopted).
+This means that changing template code can accidentally break far-off
+instantiations.
+It also means that error messages are reported only at instantiation
+time, and can be deeply nested and difficult to understand.
+This design avoids these problems through explicit required
+constraints.
+
+C++ supports template metaprogramming, which can be thought of as
+ordinary programming done at compile time using a syntax that is
+completely different than that of non-template C++.
+This design has no similar feature.
+This saves considerable complexity while losing some power and run
+time efficiency.
+
+C++ uses two-phase name lookup, in which some names are looked up in
+the context of the template definition, and some names are looked up
+in the context of the template instantiation.
+In this design all names are looked up at the point where they are
+written.
+
+In practice, all C++ compilers compile each template at the point
+where it is instantiated.
+This can slow down compilation time.
+This design offers flexibility as to how to handle the compilation of
+generic functions.
+
+#### Comparison with Rust
+
+The generics described in this design are similar to generics in
+Rust.
+
+One difference is that in Rust the association between a trait bound
+and a type must be defined explicitly, either in the crate that
+defines the trait bound or the crate that defines the type.
+In Go terms, this would mean that we would have to declare somewhere
+whether a type satisfied a constraint.
+Just as Go types can satisfy Go interfaces without an explicit
+declaration, in this design Go type arguments can satisfy a constraint
+without an explicit declaration.
+
+Where this design uses type lists, the Rust standard library defines
+standard traits for operations like comparison.
+These standard traits are automatically implemented by Rust's
+primitive types, and can be implemented by user defined types as
+well.
+Rust provides a fairly extensive list of traits, at least 34, covering
+all of the operators.
+
+Rust supports type parameters on methods, which this design does not.
+
+## Examples
+
+The following sections are examples of how this design could be used.
+This is intended to address specific areas where people have created
+user experience reports concerned with Go's lack of generics.
+
+### Map/Reduce/Filter
+
+Here is an example of how to write map, reduce, and filter functions
+for slices.
+These functions are intended to correspond to the similar functions in
+Lisp, Python, Java, and so forth.
+
+```Go
+// Package slices implements various slice algorithms.
+package slices
+
+// Map turns a []T1 to a []T2 using a mapping function.
+// This function has two type parameters, T1 and T2.
+// There are no constraints on the type parameters,
+// so this works with slices of any type.
+func Map(type T1, T2)(s []T1, f func(T1) T2) []T2 {
+	r := make([]T2, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+
+// Reduce reduces a []T1 to a single value using a reduction function.
+func Reduce(type T1, T2)(s []T1, initializer T2, f func(T2, T1) T2) T2 {
+	r := initializer
+	for _, v := range s {
+		r = f(r, v)
+	}
+	return r
+}
+
+// Filter filters values from a slice using a filter function.
+// It returns a new slice with only the elements of s
+// for which f returned true.
+func Filter(type T)(s []T, f func(T) bool) []T {
+	var r []T
+	for _, v := range s {
+		if f(v) {
+			r = append(r, v)
+		}
+	}
+	return r
+}
+```
+
+Here are some example calls of these functions.
+Type inference is used to determine the type arguments based on the
+types of the non-type arguments.
+
+```Go
+	s := []int{1, 2, 3}
+
+	floats := slices.Map(s, func(i int) float64 { return float64(i) })
+	// Now float2 is []float64{1.0, 2.0, 3.0}.
+
+	sum := slices.Reduce(s, 0, func(i, j int) int { return i + j })
+	// Now sum is 6.
+
+	evens := slices.Filter(s, func(i int) bool { return i%2 == 0 })
+	// Now evens is []int{2}.
+```
+
+### Map keys
+
+Here is how to get a slice of the keys of any map.
+
+```Go
+// Package maps provides general functions that work for all map types.
+package maps
+
+// Keys returns the keys of the map m in a slice.
+// The keys will be returned in an unpredictable order.
+// This function has two type parameters, K and V.
+// Map keys must be comparable, so key has the predeclared 
+// constraint comparable. Map values can be any type;
+// the empty interface type imposes no constraints.
+func Keys(type K comparable, V interface{})(m map[K]V) []K {
+	r := make([]K, 0, len(m))
+	for k := range m {
+		r = append(r, k)
+	}
+	return r
+}
+```
+
+In typical use the map key and val types will be inferred.
+
+```Go
+	k := maps.Keys(map[int]int{1:2, 2:4})
+	// Now k is either []int{1, 2} or []int{2, 1}.
+```
+
+### Sets
+
+Many people have asked for Go's builtin map type to be extended, or
+rather reduced, to support a set type.
+Here is a type-safe implementation of a set type, albeit one that uses
+methods rather than operators like `[]`.
+
+```Go
+// Package set implements sets of any comparable type.
+package set
+
+// Set is a set of values.
+type Set(type T comparable) map[T]struct{}
+
+// Make returns a set of some element type.
+func Make(type T comparable)() Set(T) {
+	return make(Set(T))
+}
+
+// Add adds v to the set s.
+// If v is already in s this has no effect.
+func (s Set(T)) Add(v T) {
+	s[v] = struct{}{}
+}
+
+// Delete removes v from the set s.
+// If v is not in s this has no effect.
+func (s Set(T)) Delete(v T) {
+	delete(s, v)
+}
+
+// Contains reports whether v is in s.
+func (s Set(T)) Contains(v T) bool {
+	_, ok := s[v]
+	return ok
+}
+
+// Len reports the number of elements in s.
+func (s Set(T)) Len() int {
+	return len(s)
+}
+
+// Iterate invokes f on each element of s.
+// It's OK for f to call the Delete method.
+func (s Set(T)) Iterate(f func(T)) {
+	for v := range s {
+		f(v)
+	}
+}
+```
+
+Example use:
+
+```Go
+	// Create a set of ints.
+	// We pass (int) as a type argument.
+	// Then we write () because Make does not take any non-type arguments.
+	// We have to pass an explicit type argument to Make.
+	// Type inference doesn't work because the type argument
+	// to Make is only used for a result parameter type.
+	s := set.Make(int)()
+
+	// Add the value 1 to the set s.
+	s.Add(1)
+
+	// Check that s does not contain the value 2.
+	if s.Contains(2) { panic("unexpected 2") }
+```
+
+This example shows how to use this design to provide a compile-time
+type-safe wrapper around an existing API.
+
+### Sort
+
+Before the introduction of `sort.Slice`, a common complaint was the
+need for boilerplate definitions in order to use `sort.Sort`.
+With this design, we can add to the sort package as follows:
+
+```Go
+// Ordered is a type constraint that matches all ordered types.
+// (An ordered type is one that supports the < <= >= > operators.)
+// In practice this type constraint would likely be defined in
+// a standard library package.
+type Ordered interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		string
+}
+
+// orderedSlice is an internal type that implements sort.Interface.
+// The Less method uses the < operator. The Ordered type constraint
+// ensures that T has a < operator.
+type orderedSlice(type T Ordered) []T
+
+func (s orderedSlice(T)) Len() int           { return len(s) }
+func (s orderedSlice(T)) Less(i, j int) bool { return s[i] < s[j] }
+func (s orderedSlice(T)) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// OrderedSlice sorts the slice s in ascending order.
+// The elements of s must be ordered using the < operator.
+func OrderedSlice(type T Ordered)(s []T) {
+	// Convert s to the type orderedSlice(T).
+	// As s is []T, and orderedSlice(T) is defined as []T,
+	// this conversion is permitted.
+	// orderedSlice(T) implements sort.Interface,
+	// so can pass the result to sort.Sort.
+	// The elements will be sorted using the < operator.
+	sort.Sort(orderedSlice(T)(s))
+}
+```
+
+Now we can write:
+
+```Go
+	s1 := []int32{3, 5, 2}
+	sort.OrderedSlice(s1)
+	// Now s1 is []int32{2, 3, 5}
+
+	s2 := []string{"a", "c", "b"})
+	sort.OrderedSlice(s2)
+	// Now s2 is []string{"a", "b", "c"}
+```
+
+Along the same lines, we can add a function for sorting using a
+comparison function, similar to `sort.Slice` but writing the function
+to take values rather than slice indexes.
+
+```Go
+// sliceFn is an internal type that implements sort.Interface.
+// The Less method calls the cmp field.
+type sliceFn(type T) struct {
+	s   []T
+	cmp func(T, T) bool
+}
+
+func (s sliceFn(T)) Len() int           { return len(s.s) }
+func (s sliceFn(T)) Less(i, j int) bool { return s.cmp(s.s[i], s.s[j]) }
+func (s sliceFn(T)) Swap(i, j int)      { s.s[i], s.s[j] = s.s[j], s.s[i] }
+
+// SliceFn sorts the slice s according to the function cmp.
+func SliceFn(type T)(s []T, cmp func(T, T) bool) {
+	Sort(sliceFn(E){s, cmp})
+}
+```
+
+An example of calling this might be:
+
+```Go
+	var s []*Person
+	// ...
+	sort.SliceFn(s, func(p1, p2 *Person) bool { return p1.Name < p2.Name })
+```
+
+### Channels
+
+Many simple general purpose channel functions are never written,
+because they must be written using reflection and the caller must type
+assert the results.
+With this design they become straightforward to write.
+
+```Go
+// Package chans implements various channel algorithms.
+package chans
+
+import "runtime"
+
+// Ranger provides a convenient way to exit a goroutine sending values
+// when the receiver stops reading them.
+//
+// Ranger returns a Sender and a Receiver. The Receiver provides a
+// Next method to retrieve values. The Sender provides a Send method
+// to send values and a Close method to stop sending values. The Next
+// method indicates when the Sender has been closed, and the Send
+// method indicates when the Receiver has been freed.
+func Ranger(type T)() (*Sender(T), *Receiver(T)) {
+	c := make(chan T)
+	d := make(chan bool)
+	s := &Sender(T){values: c, done: d}
+	r := &Receiver(T){values: c, done: d}
+	// The finalizer on the receiver will tell the sender
+	// if the receiver stops listening.
+	runtime.SetFinalizer(r, r.finalize)
+	return s, r
+}
+
+// A Sender is used to send values to a Receiver.
+type Sender(type T) struct {
+	values chan<- T
+	done   <-chan bool
+}
+
+// Send sends a value to the receiver. It reports whether any more
+// values may be sent; if it returns false the value was not sent.
+func (s *Sender(T)) Send(v T) bool {
+	select {
+	case s.values <- v:
+		return true
+	case <-s.done:
+		// The receiver has stopped listening.
+		return false
+	}
+}
+
+// Close tells the receiver that no more values will arrive.
+// After Close is called, the Sender may no longer be used.
+func (s *Sender(T)) Close() {
+	close(s.values)
+}
+
+// A Receiver receives values from a Sender.
+type Receiver(type T) struct {
+	values <-chan T
+	done  chan<- bool
+}
+
+// Next returns the next value from the channel. The bool result
+// reports whether the value is valid. If the value is not valid, the
+// Sender has been closed and no more values will be received.
+func (r *Receiver(T)) Next() (T, bool) {
+	v, ok := <-r.values
+	return v, ok
+}
+
+// finalize is a finalizer for the receiver.
+// It tells the sender that the receiver has stopped listening.
+func (r *Receiver(T)) finalize() {
+	close(r.done)
+}
+```
+
+There is an example of using this function in the next section.
+
+### Containers
+
+One of the frequent requests for generics in Go is the ability to
+write compile-time type-safe containers.
+This design makes it easy to write a compile-time type-safe wrapper
+around an existing container; we won't write out an example for that.
+This design also makes it easy to write a compile-time type-safe
+container that does not use boxing.
+
+Here is an example of an ordered map implemented as a binary tree.
+The details of how it works are not too important.
+The important points are:
+
+* The code is written in a natural Go style, using the key and value
+  types where needed.
+* The keys and values are stored directly in the nodes of the tree,
+  not using pointers and not boxed as interface values.
+
+```Go
+// Package orderedmap provides an ordered map, implemented as a binary tree.
+package orderedmap
+
+import "chans"
+
+// Map is an ordered map.
+type Map(type K, V) struct {
+	root    *node(K, V)
+	compare func(K, K) int
+}
+
+// node is the type of a node in the binary tree.
+type node(type K, V) struct {
+	k           K
+	v           V
+	left, right *node(K, V)
+}
+
+// New returns a new map.
+// Since the type parameter V is only used for the result,
+// type inference does not work, and calls to New must always
+// pass explicit type arguments.
+func New(type K, V)(compare func(K, K) int) *Map(K, V) {
+	return &Map(K, V){compare: compare}
+}
+
+// find looks up k in the map, and returns either a pointer
+// to the node holding k, or a pointer to the location where
+// such a node would go.
+func (m *Map(K, V)) find(k K) **node(K, V) {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(k, (*pn).k); {
+		case cmp < 0:
+			pn = &(*pn).left
+		case cmp > 0:
+			pn = &(*pn).right
+		default:
+			return pn
+		}
+	}
+	return pn
+}
+
+// Insert inserts a new key/value into the map.
+// If the key is already present, the value is replaced.
+// Reports whether this is a new key.
+func (m *Map(K, V)) Insert(k K, v V) bool {
+	pn := m.find(k)
+	if *pn != nil {
+		(*pn).v = v
+		return false
+	}
+	*pn = &node(K, V){k: k, v: v}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The bool result reports whether the key was found.
+func (m *Map(K, V)) Find(k K) (V, bool) {
+	pn := m.find(k)
+	if *pn == nil {
+		var zero val // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).v, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue(type K, V) struct {
+	k K
+	v V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map(K, V)) InOrder() *Iterator(K, V) {
+	type kv = keyValue(K, V) // convenient shorthand
+	sender, receiver := chans.Ranger(kv)()
+	var f func(*node(K, V)) bool
+	f = func(n *node(K, V)) bool {
+		if n == nil {
+			return true
+		}
+		// Stop sending values if sender.Send returns false,
+		// meaning that nothing is listening at the receiver end.
+		return f(n.left) &&
+			sender.Send(kv{n.k, n.v}) &&
+			f(n.right)
+	}
+	go func() {
+		f(m.root)
+		sender.Close()
+	}()
+	return &Iterator{receiver}
+}
+
+// Iterator is used to iterate over the map.
+type Iterator(type K, V) struct {
+	r *chans.Receiver(keyValue(K, V))
+}
+
+// Next returns the next key and value pair. The bool result reports
+// whether the values are valid. If the values are not valid, we have
+// reached the end.
+func (it *Iterator(K, V)) Next() (K, V, bool) {
+	kv, ok := it.r.Next()
+	return kv.k, kv.v, ok
+}
+```
+
+This is what it looks like to use this package:
+
+```Go
+import "container/orderedmap"
+
+// Set m to an ordered map from string to string,
+// using strings.Compare as the comparison function.
+var m = orderedmap.New(string, string)(strings.Compare)
+
+// Add adds the pair a, b to m.
+func Add(a, b string) {
+	m.Insert(a, b)
+}
+```
+
+### Append
+
+The predeclared `append` function exists to replace the boilerplate
+otherwise required to grow a slice.
+Before `append` was added to the language, there was a function `Add`
+in the bytes package:
+
+```Go
+// Add appends the contents of t to the end of s and returns the result.
+// If s has enough capacity, it is extended in place; otherwise a
+// new array is allocated and returned.
+func Add(s, t []byte) []byte
+```
+
+`Add` appended two `[]byte` values together, returning a new slice.
+That was fine for `[]byte`, but if you had a slice of some other
+type, you had to write essentially the same code to append more
+values.
+If this design were available back then, perhaps we would not have
+added `append` to the language.
+Instead, we could write something like this:
+
+```Go
+// Package slices implements various slice algorithms.
+package slices
+
+// Append appends the contents of t to the end of s and returns the result.
+// If s has enough capacity, it is extended in place; otherwise a
+// new array is allocated and returned.
+func Append(type T)(s []T, t ...T) []T {
+	lens := len(s)
+	tot := lens + len(t)
+	if tot < 0 {
+		panic("Append: cap out of range")
+	}
+	if tot > cap(s) {
+		news := make([]T, tot, tot + tot/2)
+		copy(news, s)
+		s = news
+	}
+	s = s[:tot]
+	copy(s[lens:], t)
+	return s
+}
+```
+
+That example uses the predeclared `copy` function, but that's OK, we
+can write that one too:
+
+```Go
+// Copy copies values from t to s, stopping when either slice is
+// full, returning the number of values copied.
+func Copy(type T)(s, t []T) int {
+	i := 0
+	for ; i < len(s) && i < len(t); i++ {
+		s[i] = t[i]
+	}
+	return i
+}
+```
+
+These functions can be used as one would expect:
+
+```Go
+	s := slices.Append([]int{1, 2, 3}, 4, 5, 6)
+	// Now s is []int{1, 2, 3, 4, 5, 6}.
+	slices.Copy(s[3:], []int{7, 8, 9})
+	// Now s is []int{1, 2, 3, 7, 8, 9}
+```
+
+This code doesn't implement the special case of appending or copying a
+`string` to a `[]byte`, and it's unlikely to be as efficient as the
+implementation of the predeclared function.
+Still, this example shows that using this design would permit `append`
+and `copy` to be written generically, once, without requiring any
+additional special language features.
+
+### Metrics
+
+In a [Go experience
+report](https://medium.com/@sameer_74231/go-experience-report-for-generics-google-metrics-api-b019d597aaa4)
+Sameer Ajmani describes a metrics implementation.
+Each metric has a value and one or more fields.
+The fields have different types.
+Defining a metric requires specifying the types of the fields, and
+creating a value with an Add method.
+The Add method takes the field types as arguments, and records an
+instance of that set of fields.
+The C++ implementation uses a variadic template.
+The Java implementation includes the number of fields in the name of
+the type.
+Both the C++ and Java implementations provide compile-time type-safe
+Add methods.
+
+Here is how to use this design to provide similar functionality in
+Go with a compile-time type-safe Add method.
+Because there is no support for a variadic number of type arguments,
+we must use different names for a different number of arguments, as in
+Java.
+This implementation only works for comparable types.
+A more complex implementation could accept a comparison function to
+work with arbitrary types.
+
+```Go
+// Package metrics provides a general mechanism for accumulating
+// metrics of different values.
+package metrics
+
+import "sync"
+
+// Metric1 accumulates metrics of a single value.
+type Metric1(type T comparable) struct {
+	mu sync.Mutex
+	m  map[T]int
+}
+
+// Add adds an instance of a value.
+func (m *Metric1(T)) Add(v T) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[T]int)
+	}
+	m.m[v]++
+}
+
+// key2 is an internal type used by Metric2.
+type key2(type T1, T2 comparable) struct {
+	f1 T1
+	f2 T2
+}
+
+// Metric2 accumulates metrics of pairs of values.
+type Metric2(type T1, T2 comparable) struct {
+	mu sync.Mutex
+	m  map[key2(T1, T2)]int
+}
+
+// Add adds an instance of a value pair.
+func (m *Metric2(T1, T2)) Add(v1 T1, v2 T2) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key2(T1, T2)]int)
+	}
+	m.m[key2(T1, T2){v1, v2}]++
+}
+
+// key3 is an internal type used by Metric3.
+type key3(type T1, T2, T3 comparable) struct {
+	f1 T1
+	f2 T2
+	f3 T3
+}
+
+// Metric3 accumulates metrics of triples of values.
+type Metric3(type T1, T2, T3 comparable) struct {
+	mu sync.Mutex
+	m  map[key3(T1, T2, T3)]int
+}
+
+// Add adds an instance of a value triplet.
+func (m *Metric3(T1, T2, T3)) Add(v1 T1, v2 T2, v3 T3) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.m == nil {
+		m.m = make(map[key3(T1, T2, T3)]int)
+	}
+	m.m[key3(T1, T2, T3){v1, v2, v3}]++
+}
+
+// Repeat for the maximum number of permitted arguments.
+```
+
+Using this package looks like this:
+
+```Go
+import "metrics"
+
+var m = metrics.Metric2(string, int){}
+
+func F(s string, i int) {
+	m.Add(s, i) // this call is type checked at compile time
+}
+```
+
+This implementation has a certain amount of repetition due to the lack
+of support for variadic type parameters.
+Using the package, though, is easy and type safe.
+
+### List transform
+
+While slices are efficient and easy to use, there are occasional cases
+where a linked list is appropriate.
+This example primarily shows transforming a linked list of one type to
+another type, as an example of using different instantiations of the
+same generic type.
+
+```Go
+// Package list provides a linked list of any type.
+package list
+
+// List is a linked list.
+type List(type T) struct {
+	head, tail *element(T)
+}
+
+// An element is an entry in a linked list.
+type element(type T) struct {
+	next *element(T)
+	val  T
+}
+
+// Push pushes an element to the end of the list.
+func (lst *List(T)) Push(v T) {
+	if lst.tail == nil {
+		lst.head = &element(T){val: v}
+		lst.tail = lst.head
+	} else {
+		lst.tail.next = &element(T){val: v }
+		lst.tail = lst.tail.next
+	}
+}
+
+// Iterator ranges over a list.
+type Iterator(type T) struct {
+	next **element(T)
+}
+
+// Range returns an Iterator starting at the head of the list.
+func (lst *List(T)) Range() *Iterator(T) {
+	return Iterator(T){next: &lst.head}
+}
+
+// Next advances the iterator.
+// It reports whether there are more elements.
+func (it *Iterator(T)) Next() bool {
+	if *it.next == nil {
+		return false
+	}
+	it.next = &(*it.next).next
+	return true
+}
+
+// Val returns the value of the current element.
+// The bool result reports whether the value is valid.
+func (it *Iterator(T)) Val() (T, bool) {
+	if *it.next == nil {
+		var zero T
+		return zero, false
+	}
+	return (*it.next).val, true
+}
+
+// Transform runs a transform function on a list returning a new list.
+func Transform(type T1, T2)(lst *List(T1), f func(T1) T2) *List(T2) {
+	ret := &List(T2){}
+	it := lst.Range()
+	for {
+		if v, ok := it.Val(); ok {
+			ret.Push(f(v))
+		}
+		if !it.Next() {
+			break
+		}
+	}
+	return ret
+}
+```
+
+### Dot product
+
+A generic dot product implementation that works for slices of any
+numeric type.
+
+```Go
+// Numeric is a constraint that matches any numeric type.
+// It would likely be in a constraints package in the standard library.
+type Numeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64,
+		complex64, complex128
+}
+
+// DotProduct returns the dot product of two slices.
+// This panics if the two slices are not the same length.
+func DotProduct(type T Numeric)(s1, s2 []T) T {
+	if len(s1) != len(s2) {
+		panic("DotProduct: slices of unequal length")
+	}
+	var r T
+	for i := range s1 {
+		r += s1[i] * s2[i]
+	}
+	return r
+}
+```
+
+(Note: the generics implementation approach may affect whether
+`DotProduct` uses FMA, and thus what the exact results are when using
+floating point types.
+It's not clear how much of a problem this is, or whether there is any
+way to fix it.)
+
+### Absolute difference
+
+Compute the absolute difference between two numeric values, by using
+an `Abs` method.
+This uses the same `Numeric` constraint defined in the last example.
+
+This example uses more machinery than is appropriate for the simple
+case of computing the absolute difference.
+It is intended to show how the common part of algorithms can be
+factored into code that uses methods, where the exact definition of
+the methods can vary based on the kind of type being used.
+
+```Go
+// NumericAbs matches numeric types with an Abs method.
+type NumericAbs(type T) interface {
+	Numeric
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func AbsDifference(type T NumericAbs)(a, b T) T {
+	d := a - b
+	return d.Abs()
+}
+```
+
+We can define an `Abs` method appropriate for different numeric types.
+
+```Go
+// OrderedNumeric matches numeric types that support the < operator.
+type OrderedNumeric interface {
+	type int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64
+}
+
+// Complex matches the two complex types, which do not have a < operator.
+type Complex interface {
+	type complex64, complex128
+}
+
+// OrderedAbs is a helper type that defines an Abs method for
+// ordered numeric types.
+type OrderedAbs(type T OrderedNumeric) T
+
+func (a OrderedAbs(T)) Abs() OrderedAbs(T) {
+	if a < 0 {
+		return -a
+	}
+	return a
+}
+
+// ComplexAbs is a helper type that defines an Abs method for
+// complex types.
+type ComplexAbs(type T Complex) T
+
+func (a ComplexAbs(T)) Abs() ComplexAbs(T) {
+	d := math.Hypot(float64(real(a)), float64(imag(a)))
+	return ComplexAbs(T)(complex(d, 0))
+}
+```
+
+We can then define functions that do the work for the caller by
+converting to and from the types we just defined.
+
+```Go
+// OrderedAbsDifference returns the absolute value of the difference
+// between a and b, where a and b are of an ordered type.
+func OrderedAbsDifference(type T OrderedNumeric)(a, b T) T {
+	return T(AbsDifference(OrderedAbs(T)(a), OrderedAbs(T)(b)))
+}
+
+// ComplexAbsDifference returns the absolute value of the difference
+// between a and b, where a and b are of a complex type.
+func ComplexAbsDifference(type T Complex)(a, b T) T {
+	return T(AbsDifference(ComplexAbs(T)(a), ComplexAbs(T)(b)))
+}
+```
+
+It's worth noting that this design is not powerful enough to write
+code like the following:
+
+```Go
+// This function is INVALID.
+func GeneralAbsDifference(type T Numeric)(a, b T) T {
+	switch (interface{})(a).(type) {
+	case int, int8, int16, int32, int64,
+		uint, uint8, uint16, uint32, uint64, uintptr,
+		float32, float64:
+		return OrderedAbsDifference(a, b) // INVALID
+	case complex64, complex128:
+		return ComplexAbsDifference(a, b) // INVALID
+	}
+}
+```
+
+The calls to `OrderedAbsDifference` and `ComplexAbsDifference` are
+invalid, because not all the types that implement the `Numeric`
+constraint can implement the `OrderedNumeric` or `Complex`
+constraints.
+Although the type switch means that this code would conceptually work
+at run time, there is no support for writing this code at compile
+time.
+This is another way of expressing one of the omissions listed above:
+this design does not provide for specialization.
+
+## Acknowledgements
+
+We'd like to thank many people on the Go team, many contributors to
+the Go issue tracker, and all the people who have shared their ideas
+and their feedback on earlier design drafts.
+We read all of it, and we're grateful.
+
+For this design draft in particular we received detailed feedback from
+Josh Bleecher-Snyder, Jon Bodner, Dave Cheney, Jaana Dogan, Kevin
+Gillette, Mitchell Hashimoto, Chris Hines, Bill Kennedy, Ayke van
+Laethem, Daniel Martí, Elena Morozova, Roger Peppe, and Ronna
+Steinberg.
+
+## Appendix
+
+This appendix covers various details of the design that don't seem
+significant enough to cover in earlier sections.
+
+### Generic type aliases
+
+A type alias may refer to a generic type, but the type alias may not
+have its own parameters.
+This restriction exists because it is unclear how to handle a type
+alias with type parameters that have constraints.
+
+```Go
+type VectorAlias = Vector
+```
+
+In this case uses of the type alias will have to provide type
+arguments appropriate for the generic type being aliased.
+
+```Go
+var v VectorAlias(int)
+```
+
+Type aliases may also refer to instantiated types.
+
+```Go
+type VectorInt = Vector(int)
+```
+
+### Instantiating a function
+
+Go normally permits you to refer to a function without passing any
+arguments, producing a value of function type.
+You may not do this with a function that has type parameters; all type
+arguments must be known at compile time.
+That said, you can instantiate the function, by passing type
+arguments, but you don't have to call the instantiation.
+This will produce a function value with no type parameters.
+
+```Go
+// PrintInts is type func([]int).
+var PrintInts = Print(int)
+```
+
+### Embedded type parameter
+
+When a generic type is a struct, and the type parameter is
+embedded as a field in the struct, the name of the field is the name
+of the type parameter.
+
+```Go
+// A Lockable is a value that may be safely simultaneously accessed
+// from multiple goroutines via the Get and Set methods.
+type Lockable(type T) struct {
+	T
+	mu sync.Mutex
+}
+
+// Get returns the value stored in a Lockable.
+func (l *Lockable(T)) Get() T {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	return l.T
+}
+
+// Set sets the value in a Lockable.
+func (l *Lockable(T)) Set(v T) {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	l.T = v
+}
+```
+
+### Inline constraints
+
+As we've seen in examples that use `interface{}` as a type constraint,
+it's not necessary for a constraint to use a named interface type.
+A type parameter list can use an interface type literal, just as an
+ordinary parameter list can use a type literal for a parameter type.
+
+```Go
+// Stringify calls the String method on each element of s,
+// and returns the results.
+func Stringify(type T interface { String() string })(s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String())
+	}
+	return ret
+}
+```
+
+### Type inference for composite literals
+
+This is a feature we are not suggesting now, but could consider for
+later versions of the language.
+
+We could also consider supporting type inference for composite
+literals of generic types.
+
+```Go
+type Pair(type T) struct { f1, f2 T }
+var V = Pair{1, 2} // inferred as Pair(int){1, 2}
+```
+
+It's not clear how often this will arise in real code.
+
+### Type inference for generic function arguments
+
+This is a feature we are not suggesting now, but could consider for
+later versions of the language.
+
+In the following example, consider the call to `Find` in `FindClose`.
+Type inference can determine that the type argument to `Find` is `T4`,
+and from that we know that the type of the final argument must be
+`func(T4, T4) bool`, and from that we could deduce that the type
+argument to `IsClose` must also be `T4`.
+However, the type inference algorithm described earlier cannot do
+that, so we must explicitly write `IsClose(T4)`.
+
+This may seem esoteric at first, but it comes up when passing generic
+functions to generic `Map` and `Filter` functions.
+
+```Go
+// Differ has a Diff method that returns how different a value is.
+type Differ(type T1) interface {
+	Diff(T1) int
+}
+
+// IsClose returns whether a and b are close together, based on Diff.
+func IsClose(type T2 Differ)(a, b T2) bool {
+	return a.Diff(b) < 2
+}
+
+// Find returns the index of the first element in s that matches e,
+// based on the cmp function. It returns -1 if no element matches.
+func Find(type T3)(s []T3, e T3, cmp func(a, b T3) bool) int {
+	for i, v := range s {
+		if cmp(v, e) {
+			return i
+		}
+	}
+	return -1
+}
+
+// FindClose returns the index of the first element in s that is
+// close to e, based on IsClose.
+func FindClose(type T4 Differ)(s []T4, e T4) int {
+	// With the current type inference algorithm we have to
+	// explicitly write IsClose(T4) here, although it
+	// is the only type argument we could possibly use.
+	return Find(s, e, IsClose(T4))
+}
+```
+
+### Reflection on type arguments
+
+Although we don't suggest changing the reflect package, one
+possibility to consider for the future would be to add two new
+methods to `reflect.Type`: `NumTypeArgument() int` would return the
+number of type arguments to a type, and `TypeArgument(i) Type` would
+return the i'th type argument.
+`NumTypeArgument` would return non-zero for an instantiated generic
+type.
+Similar methods could be defined for `reflect.Value`, for which
+`NumTypeArgument` would return non-zero for an instantiated generic
+function.
+There might be some kind of programs that would care about this
+information.
+
+### Instantiating types in type literals
+
+When instantiating a type at the end of a type literal, there is a
+parsing ambiguity.
+
+```Go
+x1 := []T(v1)
+x2 := []T(v2){}
+```
+
+In this example, the first case is a type conversion of `v1` to the
+type `[]T`.
+The second case is a composite literal of type `[]T(v2)`, where `T` is
+a generic type that we are instantiating with the type argument `v2`.
+The ambiguity is at the point where we see the open parenthesis: at
+that point the parser doesn't know whether it is seeing a type
+conversion or something like a composite literal.
+
+To avoid this ambiguity, we require that type instantiations at the
+end of a type literal be parenthesized.
+To write a type literal that is a slice of a type instantiation, you
+must write `[](T(v1))`.
+Without those parentheses, `[]T(x)` is parsed as `([]T)(x)`, not as
+`[](T(x))`.
+This only applies to slice, array, map, chan, and func type literals
+ending in a type name.
+Of course it is always possible to use a separate type declaration to
+give a name to the instantiated type, and to use that.
+
+### Embedding an instantiated interface type
+
+There is a parsing ambiguity when embedding an instantiated interface
+type in another interface type.
+
+```Go
+type I1(type T) interface {
+	M(T)
+}
+
+type I2 interface {
+	I1(int)
+}
+```
+
+In this example we don't know whether interface `I2` has a single
+method named `I1` that takes an argument of type `int`, or whether we
+are trying to embed the instantiated type `I1(int)` into `I2`.
+
+For backward compatibility, we treat this as the former case: `I2` has
+a method named `I1`.
+
+In order to embed an instantiated interface type, we require
+that extra parentheses be used.
+
+```Go
+type I2 interface {
+	(I1(int))
+}
+```
+
+This is currently not permitted by the language, and will be a
+relaxation of the existing rules.
+
+The same applies to embedding an instantiated type in a struct.
+
+```Go
+type S1 struct {
+	T(int) // field named T of type int
+}
+
+type S2 struct {
+	(T(int)) // embedded field of type T(int)
+}
+```
+
+The field name of an embedded field of type `T(int)` is simply `T`.
