design: add go2draft documents

These documents are being published in order to share
our current thoughts about major design issues for Go 2.
See go2draft.md for more information and links.

Change-Id: Id0580830ab5e7ac17bb38ef744dfb65ea5b3d047
Reviewed-on: https://go-review.googlesource.com/131915
Reviewed-by: Andrew Bonventre <andybons@golang.org>
diff --git a/design/go2draft-contracts.md b/design/go2draft-contracts.md
new file mode 100644
index 0000000..e4b714a
--- /dev/null
+++ b/design/go2draft-contracts.md
@@ -0,0 +1,2561 @@
+# Contracts — Draft Design
+
+Ian Lance Taylor\
+Robert Griesemer\
+August 27, 2018
+
+## Abstract
+
+We suggest extending the Go language to add optional type parameters
+to types and functions.
+Type parameters may be constrained by contracts: they may be used as
+ordinary types that only support the operations described by the
+contracts.
+Type inference via a unification algorithm is supported to permit
+omitting type arguments from function calls in many cases.
+Depending on a detail, the design can be fully backward compatible
+with Go 1.
+
+For more context, see the [generics problem overview](go2draft-generics-overview.md).
+
+## Background
+
+There have been many [requests to add additional support for generic
+programming](https://golang.org/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 by looking 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 contracts.
+
+This draft design suggests extending the Go language to add a form of
+parametric polymorphism, where the type parameters are bounded not by
+a subtyping relationship but by explicitly defined structural
+constraints.
+Among other languages that support parametric polymorphism this
+design is perhaps most similar to CLU or Ada, although the syntax is
+completely different.
+Contracts also somewhat resemble C++ concepts.
+
+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 always the same.
+
+## Design
+
+We will describe the complete design in stages based on examples.
+
+### Type parameters
+
+Generic code is code that is written using types that will be
+specified later.
+Each unspecified type is called a _type parameter_.
+When the code is used the type parameter is 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.
+
+```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)
+	}
+}
+```
+
+As you can see, 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 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
+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.
+
+Since `Print` has a type parameter, when we call it we must pass a
+type argument.
+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
+	Print(int)([]int{1, 2, 3})
+```
+
+### Type contracts
+
+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
+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 `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 that does not have a `String`
+method, the error is reported at the point of the function call.
+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
+for complete clarity.
+
+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 has a contract that type arguments need
+to implement.
+In this case, the contract 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 contract from whatever `Stringify` happens
+to do.
+If we did, a minor change to `Stringify` might change the contract.
+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 contract, and
+force users to change.
+What we want to avoid is `Stringify` changing its contract
+accidentally.
+
+This is an important rule that we believe should apply to any attempt
+to define generic programming in Go: there should be an explicit
+contract between the generic code and calling code.
+
+### Contract syntax
+
+In this design, a contract has the same general form as a function.
+The function body is never executed.
+Instead, it describes, by example, a set of types.
+
+For the `Stringify` example, we need to write a contract that says
+that the type has a `String` method that takes no arguments and
+returns a value of type `string`.
+Here is one way to write that:
+
+```Go
+contract stringer(x T) {
+	var s string = x.String()
+}
+```
+
+A contract is introduced with a new keyword `contract`.
+The definition of a contract looks like the definition of a function,
+except that the parameter types must be simple identifiers.
+
+### Using a contract to verify type arguments
+
+A contract serves two purposes.
+First, contracts are used to validate a set of type arguments.
+As shown above, when a function with type parameters is called, it
+will be called with a set of type arguments.
+When the compiler sees the function call, it will use the contract to
+validate the type arguments.
+If the type arguments are invalid, the compiler will report a type
+error: the call is using types that the function’s contract does not
+permit.
+
+To validate the type arguments, each of the contract’s parameter types
+is replaced with the corresponding type argument (there must be
+exactly as many type arguments as there are parameter types; contracts
+may not be variadic).
+The body of the contract is then type checked as though it were an
+ordinary function.
+If the type checking succeeds, the type arguments are valid.
+
+In the example of the `stringer` contract seen earlier, we can see
+that the type argument used for `T` must have a `String` method (or it
+must be a struct with a `String` field of function type).
+The `String` method must not take any arguments, and it must return a
+value of a type that is assignable to `string`. (As it happens, the
+only type assignable to `string` is, in fact, `string`.)
+If any of those statements about the type argument are not true, the
+contract body will fail when it is type checked.
+
+### The party of the second part
+
+A contract is not used only at the call site.
+It is also used to describe what the function using the contract, the
+function with type parameters, is permitted to do with those type
+parameters.
+
+In a function with type parameters that does not use a contract, such
+as the `Print` example shown earlier, the function is only permitted
+to use those type parameters in ways that any type may be used in Go.
+That is, operations like:
+
+* 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
+* define and use other types that use those types, such as a slice of
+  that type
+
+If the function wants to take any more specific action with the type
+parameter, or a value of the type parameter, the contract must permit
+it.
+Basically, if the contract body uses a type in a certain way, the
+actual function is permitted to use the type in the same way.
+This is described in more detail later.
+For now, look at the `stringer` contract example above.
+The single statement in the contract body shows that given a value of
+type `T`, the function using the `stringer` contract is permitted to
+call a method of type `String`, passing no arguments, to get a value
+of type `string`.
+That is, naturally, exactly the operation that the `Stringify`
+function needs.
+
+### Using a contract
+
+We’ve seen how the `stringer` contract can be used to verify that a
+type argument is suitable for the `Stringify` function, and we’ve seen
+how the contract permits the `Stringify` function to call the `String`
+method that it needs.
+The final step is showing how the `Stringify` function uses the
+`stringer` contract.
+This is done by naming the contract at the end of the list of type
+parameters.
+
+```Go
+func Stringify(type T stringer)(s []T) (ret []string) {
+	for _, v := range s {
+		ret = append(ret, v.String()) // now valid
+	}
+	return ret
+}
+```
+
+The list of type parameters (in this case, a list of one element) is
+followed by an optional contract name.
+The contract must have the same number of parameters as the function
+has type parameters; when validating the contract, the type parameters
+are passed to the function in the order in which they appear in the
+function definition.
+
+### Contract syntactic details
+
+Before we continue, let’s cover a few details of the contract syntax.
+
+#### Passing explicit types to a contract
+
+Although the normal case is for a function to validate the contract
+with its exact list of type parameters, the contract can also be used
+with a different set of types.
+
+For example, this simple contract says that a value of type `From` may
+be converted to the type `To`.
+
+```Go
+contract convertible(_ To, f From) {
+	To(f)
+}
+```
+
+Note that this contract body is quite simple.
+It is a single statement expression that consists of a conversion
+expression.
+Since the contract body is never executed, it doesn’t matter that the
+result of the conversion is not assigned to anything.
+All that matters is whether the conversion expressed can be type
+checked.
+
+For example, this contract would permit the type arguments `(int64,
+int32)` but would forbid the type arguments `([]int, complex64)`.
+
+Given this contract, we can write this function, which may be invoked
+with any type that can be converted to `uint64`.
+
+```Go
+func FormatUnsigned(type T convertible(uint64, T))(v T) string {
+	return strconv.FormatUint(uint64(v), 10)
+}
+```
+
+This could be called as, for example,
+
+```Go
+	s := FormatUnsigned(rune)('a')
+```
+
+This isn’t too useful with what we’ve described so far, but it will be
+a bit more convenient when we get to type inference.
+
+#### Restrictions on contract bodies
+
+Although a contract looks like a function body, contracts may not
+themselves have type parameters.
+Contracts may also not have result parameters, and it follows that
+they may not use a `return` statement to return values.
+
+The body of a contract may not refer to any name defined in the
+current package.
+This rule is intended to make it harder to accidentally change the
+meaning of a contract.
+As a compromise, a contract is permitted to refer to names imported
+from other packages, permitting a contract to easily say things like
+"this type must support the `io.Reader` interface:"
+
+```Go
+contract Readable(r T) {
+	io.Reader(r)
+}
+```
+
+It is likely that this rule will have to be adjusted as we gain more
+experience with this design.
+For example, perhaps we should permit contracts to refer to exported
+names defined in the same package, but not unexported names.
+Or maybe we should have no such restriction and just rely on
+correct programming supported by tooling.
+
+As contract bodies are not executed, there are no restrictions about
+unreachable statements, or `goto` statements across declarations, or
+anything along those lines.
+
+Of course, it is completely pointless to use a `goto` statement, or a
+`break`, `continue`, or `fallthrough` statement, in a contract body,
+as these statements do not say anything about the type arguments.
+
+#### The contract keyword
+
+Contracts may only appear at the top level of a package.
+
+While contracts could be defined to work within the body of a
+function, it’s hard to think of realistic examples in which they would
+be useful.
+We see this as similar to the way that methods can not be defined
+within the body of a function.
+A minor point is that only permitting contracts at the top level
+permits the design to be Go 1 compatible.
+
+There are a few ways to handle the syntax:
+
+* We could make `contract` be a keyword only at the start of a
+  top-level declaration, and otherwise be a normal identifier.
+* We could declare that if you use `contract` at the start of a
+  top-level declaration, then it becomes a keyword for the duration of
+  that package.
+* We could make `contract` always be a keyword, albeit one that can
+  only appear in one place, in which case this design is not Go 1
+  compatible.
+
+#### Exported contracts
+
+Like other top level declarations, a contract is exported if its name
+starts with an upper-case letter.
+An exported contract may be used by functions, types, or contracts in other
+packages.
+
+### Multiple type parameters
+
+Although the examples shown so far only use a single type parameter,
+naturally functions may have multiple type parameters.
+
+```Go
+func Print2(type T1, T2)(s1 []T1, s2 []T2) { ... }
+```
+
+Compare this to
+
+```Go
+func Print2Same(type T1)(s1 []T1, s2 []T1) { ... }
+```
+
+In `Print2` `s1` and `s2` may be slices of different types.
+In `Print2Same` `s1` and `s2` must be slices of the same element
+type.
+
+Although functions may have multiple type parameters, they may only
+have a single contract.
+
+```Go
+contract viaStrings(t To, f From) {
+	var x string = f.String()
+	t.Set(string("")) // could also use t.Set(x)
+}
+
+func SetViaStrings(type To, From viaStrings)(s []From) []To {
+	r := make([]To, len(s))
+	for i, v := range s {
+		r[i].Set(v.String())
+	}
+	return r
+}
+```
+
+### Parameterized types
+
+We want more than just generic functions: we also want generic types.
+We suggest that types be extended to take type parameters.
+
+```Go
+type Vector(type Element) []Element
+```
+
+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 parameterized 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_.
+
+```Go
+var v Vector(int)
+```
+
+Parameterized types can have methods.
+The receiver type of a method must list the type parameters.
+They are listed without the `type` keyword or any contract.
+
+```Go
+func (v *Vector(Element)) Push(x Element) { *v = append(*v, x) }
+```
+
+A parameterized 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.
+This restriction avoids an infinite recursion of type instantiation.
+
+```Go
+// This is OK.
+type List(type Element) struct {
+	next *List(Element)
+	val  Element
+}
+
+// This is INVALID.
+type P(type Element1, Element2) struct {
+	F *P(Element2, Element1) // INVALID; must be (Element1, Element2)
+}
+```
+
+(Note: with more understanding of how people want to write code, it
+may be possible to relax the reference rule to permit some cases that
+use different type arguments.)
+
+When a parameterized 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, not the name of the type argument.
+
+```Go
+type Lockable(type T) struct {
+	T
+	mu sync.Mutex
+}
+
+func (l *Lockable(T)) Get() T {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	return l.T
+}
+```
+
+(Note: this works poorly if you write `Lockable(X)` in the method
+declaration: should the method return `l.T` or `l.X`?
+Perhaps we should simply ban embedding a type parameter in a struct.)
+
+### Parameterized type aliases
+
+Type aliases may have parameters.
+
+```Go
+type Ptr(type Target) = *Target
+```
+
+Type aliases may refer to parameterized types, in which case any uses
+of the type alias (other than in another type alias declaration) must
+provide type arguments.
+
+```Go
+type V = Vector
+var v2 V(int)
+```
+
+Type aliases may refer to instantiated types.
+
+```Go
+type VectorInt = Vector(int)
+```
+
+### Methods may not take additional type arguments
+
+Although methods of a parameterized 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 top-level function.
+
+Making this decision avoids having to specify the details of exactly
+when a method with type arguments implements an interface.
+(This is a feature that can perhaps be added later if it proves
+necessary.)
+
+### Contract embedding
+
+A contract may embed another contract, by listing it in the
+contract body with type arguments.
+This will look like a function call in the contract body, but since
+the call is to a contract it is handled as if the called contract’s
+body were embedded in the calling contract, with the called contract’s
+type parameters replaced by the type arguments provided in the
+contract call.
+
+This contract embeds the contract `stringer` defined earlier.
+
+```Go
+contract PrintStringer(x X) {
+	stringer(X)
+	x.Print()
+}
+```
+
+This is roughly equivalent to
+
+```Go
+contract PrintStringer(x X) {
+	var s string = x.String()
+	x.Print()
+}
+```
+
+It’s not exactly equivalent: the contract can’t refer to the variable
+`s` after embedding `stringer(X)`.
+
+### Using types that refer to themselves in contracts
+
+Although this is implied by what has already been discussed, it’s
+worth pointing out explicitly that a contract may require a method to
+have an argument whose type is one of the contract’s type parameters.
+
+```Go
+package comparable
+
+// The equal contract describes types that have an Equal method for
+// the same type.
+contract equal(v T) {
+	// All that matters is type checking, so reusing v as the argument
+	// means that the type argument must have a Equal method such that
+	// the type argument itself is assignable to the Equal method’s
+	// parameter type.
+	var x bool = v.Equal(v)
+}
+
+// Index returns the index of e in s, or -1.
+func Index(type T equal)(s []T, e T) int {
+	for i, v := range s {
+		// Both e and v are type T, so it’s OK to call e.Equal(v).
+		if e.Equal(v) {
+			return i
+		}
+	}
+	return -1
+}
+```
+
+This function can be used with any type that has an `Equal` method
+whose single parameter type is the type itself.
+
+```Go
+import "comparable"
+
+type EqualInt int
+
+// The Equal method lets EqualInt implement the comparable.equal contract.
+func (a EqualInt) Equal(b EqualInt) bool { return a == b }
+
+func Index(s []EqualInt, e EqualInt) int {
+	return comparable.Index(EqualInt)(s, e)
+}
+```
+
+In this example, when we pass `EqualInt` to `comparable.Index`, we
+check whether `EqualInt` satisfies the contract `comparable.equal`.
+We replace `T` in the body of `comparable.equal` with `EqualInt`, and
+see whether the result type checks.
+`EqualInt` has a method `Equal` that accepts a parameter of type
+`EqualInt`, so all is well, and the compilation succeeds.
+
+### Mutually referential type parameters
+
+Within a contract body, expressions may arbitrarily combine values of
+any type parameter.
+
+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
+
+contract G(n Node, e Edge) {
+	var _ []Edge = n.Edges()
+	var from, to Node = e.Nodes()
+}
+
+type Graph(type Node, Edge G) struct { ... }
+func New(type Node, Edge G)(nodes []Node) *Graph(Node, Edge) { ... }
+func (*Graph(Node, Edge)) ShortestPath(from, to Node) []Edge { ... }
+```
+
+At first glance it might be hard to see how this differs from similar
+code using interface types.
+The difference is that although `Node` and `Edge` have specific
+methods, they are not interface types.
+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.
+
+For example, consider these type definitions in some other package:
+
+```Go
+type Vertex struct { ... }
+func (v *Vertex) Edges() []*FromTo { ... }
+type FromTo struct { ... }
+type (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 contract `graph.G`.
+Because of the way that the contract is written, we could also use the
+non-pointer types `Vertex` and `FromTo`; the contract implies that the
+function body will always be able to take the address of the argument
+if necessary, and so will always be able to call the pointer method.
+
+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 `graph.G` contract.
+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.
+
+### 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 contrast to interface values, values of instantiated polymorphic types are not boxed.
+For example, let’s consider a function that works for any type `T`
+with a `Set(string)` method that initializes the value based on a
+string, and uses it to convert a slice of `string` to a slice of `T`.
+
+```Go
+package from
+
+contract setter(x T) {
+	var _ error = x.Set(string)
+}
+
+func Strings(type T setter)(s []string) ([]T, error) {
+	ret := make([]T, len(s))
+	for i, v := range s {
+		if err := ret[i].Set(v); err != nil {
+			return nil, err
+		}
+	}
+	return ret, nil
+}
+```
+
+Now let’s see some code in a different package.
+
+```Go
+type Settable int
+
+func (p *Settable) Set(s string) (err error) {
+	*p, err = strconv.Atoi(s)
+	return err
+}
+
+func F() {
+	// The type of nums is []Settable.
+	nums, err := from.Strings(Settable)([]string{"1", "2"})
+	// 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 values in that slice will be `Settable` values, which is to say,
+they will be integers.
+They will not be boxed as pointers, even though they were created and
+set by a generic function.
+
+Similarly, when a parameterized type is instantiated it will have the
+expected types as fields.
+
+```Go
+package pair
+
+type Pair(type carT, cdrT) struct {
+	f1 carT
+	f2 cdrT
+}
+```
+
+When this is instantiated, the fields will not be boxed, and no
+unexpected memory allocations will occur.
+The type `pair.Pair(int, string)` is convertible to `struct { f1 int;
+f2 string }`.
+
+### 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 of a call to our 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 it is not possible to infer the type arguments for the
+function.
+For example, when calling `from.Strings` as defined earlier, the type
+parameters cannot be inferred because the function’s type parameter
+`T` is not used for an input parameter, only for a result.
+
+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 here is simply `[]int`.
+On the function side is the list of the types of the function’s
+non-type parameters, which here is `[]T`.
+In the lists, we discard 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, untyped constants on the caller side, and their
+corresponding types in the function definition, are ignored.
+
+Corresponding types in the lists are compared.
+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, 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, determine the default
+type of the untyped constant in [the usual
+way](https://golang.org/ref/spec#Constants).
+Then 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
+package transform
+
+func Slice(type From, To)(s []From, f func(From) To) []To {
+	r := make([]To, len(s))
+	for i, v := range s {
+		r[i] = f(v)
+	}
+	return r
+}
+```
+
+The two type parameters `From` and `To` are both used for input
+parameters, so type inference is possible.
+In the call
+
+```Go
+	strs := transform.Slice([]int{1, 2, 3}, strconv.Itoa)
+```
+
+we unify `[]int` with `[]From`, matching `From` with `int`.
+We unify the type of `strconv.Itoa`, which is `func(int) string`,
+with `func(From) To`, matching `From` with `int` and `To` with
+`string`.
+`From` is matched twice, both times with `int`.
+Unification succeeds, changing the call from `transform.Slice` to
+`transform.Slice(int, string)`.
+
+To see the untyped constant rule in effect, consider
+
+```Go
+package pair
+
+func New(type T)(f1, f2 T) *Pair(T) { ... }
+```
+
+In the call `pair.New(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 `T` with `int`,
+so the final call is `pair.New(int)(1, 2)`.
+
+In the call `pair.New(1, int64(2))` the first argument is an untyped
+constant, so we ignore it in the first pass.
+We then unify `int64` with `T`.
+At this point the type parameter corresponding to the untyped constant
+is fully determined, so the final call is `pair.New(int64)(1, int64(2))`.
+
+In the call `pair.New(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 `T` with both `int` and `float64`, so
+unification fails, and we report a compilation error.
+
+Note that type inference is done without regard to contracts.
+First we use type inference to determine the type arguments to use for
+the package, and then, if that succeeds, we check whether those type
+arguments implement the contract.
+
+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.
+This need not be the case when untyped constants are involved.
+
+(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 is
+likely to significantly reduce the stutter of repeated type arguments
+in code.)
+
+(Note: We could also consider supporting type inference in composite
+literals.
+
+```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.)
+
+### 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.
+However, you can instantiate the function, by passing type arguments,
+without passing any non-type arguments.
+This will produce an ordinary function value with no type parameters.
+
+```Go
+// PrintInts will have type func([]int).
+var PrintInts = Print(int)
+```
+
+### Type assertions and switches
+
+A useful function with type parameters will support any type argument
+that implements the contract.
+Sometimes, though, it’s possible to use a more efficient
+implementation for some type arguments.
+The language already has mechanisms for code to find out what type it
+is working with: type assertions and type switches.
+Those are normally only permitted with interface types.
+In this design, functions are also permitted to use them with values
+whose types are type parameters, or based on type parameters.
+
+This doesn’t add any functionality, as the function could get the same
+information using the reflect package.
+It’s merely occasionally convenient, and it may result in more
+efficient code.
+
+For example, this code is permitted even if it is called with a type
+argument that is not an interface type.
+
+```Go
+contract byteReader(x T) {
+	// This expression says that x is convertible to io.Reader, or,
+	// in other words, that x has a method Read([]byte) (int, error).
+	io.Reader(x)
+}
+
+func ReadByte(type T byteReader)(r T) (byte, error) {
+	if br, ok := r.(io.ByteReader); ok {
+		return br.ReadByte()
+	}
+	var b [1]byte
+	_, err := r.Read(b[:])
+	return b[0], err
+}
+```
+
+### 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 parameterized type that we are instantiating with the type argument
+`v2`.
+The ambiguity is at the point where we see the 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.
+In other words, we always parse `[]T(v1)` as a type conversion, not as
+a potential instantiation of `T`.
+To write a type literal that is a slice of a type instantiation, you
+must write `[](T(v1))`.
+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.
+This is only an issue when the type is instantiated in place.
+
+### 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.
+
+### Contracts details
+
+Let’s take a deeper look at contracts.
+
+Operations on values whose type is a type parameter must be permitted
+by the type parameter’s contract.
+This means that the power of generic functions is tied precisely to
+the interpretation of the contract body.
+It also means that the language requires a precise definition of the
+operations that are permitted by a given contract.
+
+The general guideline is straightforward: if a statement appears in a
+contract, then that same statement may appear in a function using that
+contract.
+However, that guideline is clearly too limiting; it essentially
+requires that the function body be copied into the contract body,
+which makes the contract pointless.
+Therefore, what needs to be clearly spelled out is the ways in which a
+statement in a contract body can permit other kinds of expressions or
+statements in the function body.
+We don’t need to explain the meaning of every statement that can
+appear in a contract body, only the ones that permit operations other
+than an exact copy of the statement.
+
+#### Methods
+
+All the contracts we’ve seen so far show only method calls and type
+conversions in the contract body.
+If a method call appears in the contract body, that method may be
+called on an addressable value in any statement or expression in the
+function body.
+It will take argument and result types as shown in the contract body.
+
+The examples above use `var` declarations to specify the types of the
+result parameters.
+While it is valid to use a short declaration like `s := x.String()` in
+a contract body, such a declaration says nothing about the result
+type.
+This would match a type argument with a `String` method that returns a
+single result of any type.
+It would not permit the function using the contract to use the result
+of `x.String()`, since the type would not be known.
+
+There are a few aspects to a method call that can not be shown in a
+simple assignment statement like the ones shown above.
+
+* There is no way to specify that a method does not return any
+  values.
+* There is no way to specify that a method takes variadic arguments.
+* There is no way to distinguish a method call from a call of a struct
+  field with function type.
+
+When a contract needs to describe one of these cases, it can use a
+type conversion to an interface type.
+The interface type permits the method to be precisely described.
+If the conversion to the interface type passes the type checker, then
+the type argument must have a method of that exact type.
+
+An explicit method call, or a conversion to an interface type, can not
+be used to distinguish a pointer method from a value method.
+When the function body calls a method on an addressable value, this
+doesn’t matter; since all value methods are part of the pointer type’s
+method set, an addressable value can call either pointer methods or
+value methods.
+
+However, it is possible to write a function body that can only call
+a value method, not a pointer method.  For example:
+
+```Go
+contract adjustable(x T) {
+	var _ T = x.Adjust()
+	x.Apply()
+}
+
+func Apply(type T adjustable)(v T) {
+	v.Adjust().Apply() // INVALID
+}
+```
+
+In this example, the `Apply` method is not called on an addressable
+value.
+This can only work if the `Apply` method is a value method.
+But writing `x.Apply()` in the contract permits a pointer method.
+
+In order to use a value method in the function body, the contract must
+express that the type has a value method rather than a pointer
+method.
+That can be done like this:
+
+```Go
+contract adjustable(x T) {
+	var _ T = x.Adjust()
+	var f func() T
+	f().Apply()
+}
+```
+
+The rule is that if the contract body contains a method call on a
+non-addressable value, then the function body may call the method on a
+non-addressable value.
+
+#### Operators
+
+Method calls are not sufficient for everything we want to express.
+Consider this simple function that reports whether a parameterized
+slice contains an element.
+
+```Go
+func Contains(type T)(s []T, e T) bool {
+	for _, v := range s {
+		if v == e { // INVALID
+			return true
+		}
+	}
+	return false
+}
+```
+
+Any reasonable generics implementation should let you write this
+function.
+The problem is the expression `v == e`.
+That assumes that `T` supports the `==` operator, but there is no
+contract requiring that.
+Without a contract the function body can only use operations that are
+available for all types, but not all Go types support `==` (you can
+not use `==` to compare values of slice, map, or function type).
+
+This is easy to address using a contract.
+
+```Go
+contract comparable(x T) {
+	x == x
+}
+
+func Contains(type T comparable)(s []T, e T) bool {
+	for _, v := range s {
+		if v == e { // now valid
+			return true
+		}
+	}
+	return false
+}
+```
+
+In general, using an operator in the contract body permits using the
+same operator with the same types anywhere in the function body.
+
+For convenience, some operators also permit additional operations.
+
+Using a binary operator in the contract body permits not only using
+that operator by itself, but also the assignment version with `=`
+appended if that exists.
+That is, an expression like `x * x` in a contract body means that
+generic code, given variables `a` and `b` of the type of `x`, may
+write `a * b` and may also write `a *= b`.
+
+Using the `==` operator with values of some type as both the left and
+right operands means that the type must be comparable, and implies
+that both `==` and `!=` may be used with values of that type.
+Similarly, `!=` permits `==`.
+
+Using the `<` operator with values of some type as both the left and
+right operators means that the type must ordered, and implies that all
+of `==`, `!=`, `<`, `<=`, `>=`, and `>` may be used with values of
+that type.
+Similarly for `<=`, `>=`, and `>`.
+
+These additional operations permit a little more freedom when writing
+the body of a function with type parameters: one can convert from `a =
+a * b` to `a *= b`, or make the other changes listed above, without
+having to modify the contract.
+
+#### Type conversions
+
+As already shown, the contract body may contain type conversions.
+A type conversion in the contract body means that the function body
+may use the same type conversion in any expression.
+
+Here is an example that implements a checked conversion between
+numeric types:
+
+```Go
+package check
+
+contract convert(t To, f From) {
+	To(f)
+	From(t)
+	f == f
+}
+
+func Convert(type To, From convert)(from From) To {
+	to := To(from)
+	if From(to) != from {
+		panic("conversion out of range")
+	}
+	return to
+}
+```
+
+Note that the contract needs to explicitly permit both converting `To`
+to `From` and converting `From` to `To`.
+The ability to convert one way doesn’t necessarily imply being able to
+convert the other way; consider `check.Convert(int, interface{})(0, 0)`.
+
+#### Untyped constants
+
+Some functions are most naturally written using untyped constants.
+The contract body needs ways to say that it is possible to convert an
+untyped constant to some type.
+This is most naturally written as an assignment from an untyped
+constant.
+
+```Go
+contract untyped(x T) {
+	x = 0
+}
+```
+
+A contract of this form must be used in order to write code like `var
+v T = 0`.
+
+If a contract body has assignments with string (`x = ""`) or bool (`x
+= false`) untyped constants, the function body is permitted to use any
+untyped `string` or `bool` constant, respectively, with values of the
+type.
+
+For numeric types, the use of a single untyped constant only permits
+using the exact specified value.
+Using two untyped constant assignments for a type permits using those
+constants and any value in between.
+For complex untyped constants, the real and imaginary values may vary
+to any values between the two constants.
+
+Here is an example that adds 1000 to each element of a slice.
+If the contract did not say `x = 1000`, the expression `v + 1000` would be
+invalid.
+
+```Go
+contract add1K(x T) {
+	x = 1000
+	x + x
+}
+
+func Add1K(type T add1K)(s []T) {
+	for i, v := range s {
+		s[i] = v + 1000
+	}
+}
+```
+
+These untyped constant rules are not strictly required.
+A type conversion expression such as `T(int)` permits converting any
+`int` value to the type `T`, so it would permit code like `var x T =
+T(1000)`.
+What the untyped constant expressions permit is `var x T = 1000`,
+without the explicit type conversion.
+(Note that `int8` satisfies the `untyped` contract but not `add1K`,
+since 1000 is out of range for `int8`.)
+
+#### Booleans
+
+In order to use a value of a type parameter as a condition in an `if`
+or `for` statement, write an `if` or `for` statement in the contract
+body: `if T {}` or `for T {}`.
+This is only useful to instantiate a type parameter with a named
+boolean type, and as such is unlikely to arise much in practice.
+
+#### Sequences
+
+Some simple operations in the contract body make it easier for the
+function body to work on various sorts of sequences.
+
+Using an index expression `x[y]` in a contract body permits using an
+index expression with those types anywhere in the function body.
+For anything other than a map type, the type of `y` will normally be
+`int`; that case may also be written as `x[0]`.
+Naturally, `z = x[y]` permits an index expression yielding the
+specified type.
+
+A statement like `x[y] = z` in the contract body permits the function
+body to assign to an index element using the given types.
+Again `x[0] = z` permits assignment using any `int` index.
+
+A statement like `for x, y = range z {}` in the contract body permits
+using either a one-element or a two-element `range` clause in a `for`
+statement in the function body.
+
+Using an expression like `len(x)` or `cap(x)` in the contract body
+permits those builtin functions to be used with values of that type
+anywhere in the function body.
+
+Using contracts of this sort can permit operations on generic sequence
+types.
+For example, here is a version of `Join` that may be instantiated with
+either `[]byte` or `string`.
+This example is imperfect in that in the `string` case it will do some
+unnecessary conversions to `[]byte` in order to call `append` and
+`copy`, but perhaps the compiler can eliminate those.
+
+```Go
+contract strseq(x T) {
+	[]byte(x)
+	T([]byte{})
+	len(x)
+}
+
+func Join(type T strseq)(a []T, sep T) (ret T) {
+	if len(a) == 0 {
+		// Use the result parameter as a zero value;
+		// see discussion of zero value below.
+		return ret
+	}
+	if len(a) == 1 {
+		return T(append([]byte(nil), []byte(a[0])...))
+	}
+	n := len(sep) * (len(a) - 1)
+	for i := 0; i < len(a); i++ {
+		n += len(a[i])
+	}
+
+	b := make([]byte, n)
+	bp := copy(b, []byte(a[0]))
+	for _, s := range a[1:] {
+		bp += copy(b[bp:], []byte(sep))
+		bp += copy(b[bp:], []byte(s))
+	}
+	return T(b)
+}
+```
+
+#### Fields
+
+Using `x.f` in a contract body permits referring to the field in any
+expression in the function body.
+The contract body can use `var y = x.f` to describe the field’s type.
+
+```Go
+package move
+
+contract counter(x T) {
+	var _ int = x.Count
+}
+
+contract counters(T1, T2) { // as with a func, parameter names may be omitted.
+	// Use contract embedding to say that both types must have a
+	// Count field of type int.
+	counter(T1)
+	counter(T2)
+}
+
+func Corresponding(type T1, T2 counters)(p1 *T1, p2 *T2) {
+	p1.Count = p2.Count
+}
+```
+
+The function `move.Corresponding` will copy the `Count` field from one
+struct to the other.
+The structs may be entirely different types, as long as they both have
+a `Count` field with type `int`.
+
+A field reference in a contract body also permits using a keyed
+composite literal in the function body, as in `T1{Count: 0}`.
+
+#### Impossible contracts
+
+It is possible to write a contract body that cannot be implemented by
+any Go type.
+This is not forbidden.
+An error will be reported not when the contract or function or type is
+compiled, but on any attempt to instantiate it.
+This eliminates the need for the language spec to provide an
+exhaustive set of rules describing when a contract body cannot be
+satisfied.
+
+It may be appropriate to add a vet check for this, if possible.
+
+### 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 design is long and detailed, it reduces to a few major
+points.
+
+* Functions and types can have type parameters, which are defined
+  using optional contracts.
+* Contracts describe the operations permitted for a type parameter
+  and required for a type argument.
+* Type inference can sometimes permit omitting type arguments when
+  calling functions with type parameters.
+
+This design is completely backward compatible, in that any valid Go 1
+program will still be valid if this design is adopted (assuming
+`contract` is treated as a pseudo-keyword that is only meaningful at
+top level).
+
+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 minor for people reading
+generic code, rather than writing it.
+Naturally people must learn the new syntax for declaring type
+parameters.
+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 contracts serve effectively as documentation,
+describing the type.
+
+We expect that most people will not write generic code themselves, but
+many people are likely to write packages that use generic code written
+by others.
+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.
+
+People 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.
+
+For the minority of people writing generic packages, we expect that
+the most complicated part will be writing correct contract bodies.
+Good compiler error messages will be essential, and they seem entirely
+feasible.
+We can’t deny the additional complexity here, but we believe that the
+design avoids confusing cases and provides the facilities that
+people need to write whatever generic code is desired.
+
+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.
+
+Packages like `container/list` and `container/ring`, and types like
+`sync.Map`, will be updated to be compile-time type-safe.
+
+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.
+
+It is likely that new special purpose compile-time type-safe container
+types will be developed, and some may become widely used.
+
+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 package 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 (other than
+  using type assertions or type switches).
+* 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 parameterized type other than to
+  instantiate it.
+* No covariance or contravariance.
+* 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]`.
+  Similarly, there is no way to use `range` with a generic container
+  type.
+* No currying.
+  There is no way to specify only some of the type arguments, other
+  than by using a type alias or a helper function.
+* No adaptors.
+  There is no way for a contract to define adaptors that could be used
+  to support type arguments that do not already satisfy the contract,
+  such as, for example, defining an `==` operator in terms of an
+  `Equal` method.
+* No parameterization on non-type values.
+  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 with 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 by using
+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`.
+
+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 ugly but works with the existing design.
+* 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).
+
+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 be the best, but perhaps something
+better is possible.
+
+##### What does := mean in a contract body?
+
+If a contract body uses a short declaration, such as
+
+```Go
+	s := x.String()
+```
+
+this does not provide any information about the result parameter of
+the `String` method.
+This contract body would match any type with a `String` method that
+returns a single result of any type.
+It’s less clear what it permits in the function using this contract.
+For example, does it permit the function to call the `String` method
+and assign the result to a variable of empty interface type?
+
+##### Pointer vs. value methods in contracts
+
+It seems that the natural ways to write a contract calling for certain
+methods to exist will accept either a pointer method or a value
+method.
+That may be confusing, in that it will prevent writing a function body
+that requires a value method.
+We will have to judge from experience how much this confuses people in
+practice.
+
+##### Copying the function body into the contract body
+
+The simplest way to ensure that a function only performs the
+operations permitted by its contract is to simply copy the function
+body into the contract body.
+In other words, to make the function body be its own contract, much as
+C++ does.
+If people take this path, then this design in effect creates a lot of
+additional complexity for no benefit.
+
+We think this is unlikely because we believe that most people will not
+write generic function, and we believe that most generic functions
+will have only non-existent or trivial requirements on their type
+parameters.
+More experience will be needed to see whether this is a problem.
+
+#### Discarded ideas
+
+This design is not perfect, and it will be changed 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.
+
+##### Why not use interfaces instead of contracts?
+
+_The interface method syntax is familiar._
+_Writing contract bodies with `x + x` is ordinary Go syntax, but it_
+_is stylized, repetitive, and looks weird._
+
+It is unclear how to represent operators using interface methods.
+We considered syntaxes like `+(T, T) T`, but that is confusing and
+repetitive.
+Also, a minor point, but `==(T, T) bool` does not correspond to the
+`==` operator, which returns an untyped boolean value, not `bool`.
+We also considered writing simply `+` or `==`.
+That seems to work but unfortunately the semicolon insertion rules
+require writing a semicolon after each operator at the end of a line.
+Using contracts that look like functions gives us a familiar syntax at
+the cost of some repetition.
+These are not fatal problems, but they are difficulties.
+
+##### 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 package.
+
+It also confuses package boundaries with type definitions.
+There is no particular reason to think that the uses of parameterized
+types will break down neatly into packages.
+Sometimes they will, sometimes they won’t.
+
+##### Why not use `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 simple.
+
+##### Why not use `F[T]`?
+
+When parsing a type declaration `type A [T] int` it’s ambiguous
+whether this is a parameterized type defined (uselessly) as `int` or
+whether it is an array type with `T` elements.
+
+##### Why not use `F«T»`?
+
+We considered it but we couldn’t bring ourselves to require
+non-ASCII.
+
+##### Why not define contracts in a standard package?
+
+_Instead of writing out contracts, use names like_
+_`contracts.Arithmetic` and `contracts.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 not introduce new
+names.
+Instead we introduce one new keyword and some new syntax.
+
+We expect that if people find such names useful, we can introduce a
+package `contracts` that defines the useful names in the form of
+contracts that can be used by other types and functions and embedded
+in other contracts.
+
+#### 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 contracts.
+
+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.
+
+### 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.
+
+#### 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
+contract ordered(e Ele) { e < e }
+
+type orderedSlice(type Ele ordered) []Ele
+
+func (s orderedSlice(Ele)) Len() int           { return len(s) }
+func (s orderedSlice(Ele)) Less(i, j int) bool { return s[i] < s[j] }
+func (s orderedSlice(Ele)) 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 Ele ordered)(s []Ele) {
+	sort.Sort(orderedSlice(Ele)(s))
+}
+```
+
+Now we can write:
+
+```Go
+	sort.OrderedSlice(int32)([]int32{3, 5, 2})
+```
+
+We can rely on type inference to omit the type argument list:
+
+```Go
+	sort.OrderedSlice([]string{"a", "c", "b"})
+```
+
+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
+type sliceFn(type Ele) struct {
+	s []Ele
+	f func(Ele, Ele) bool
+}
+
+func (s sliceFn(Ele)) Len() int           { return len(s.s) }
+func (s sliceFn(Ele)) Less(i, j int) bool { return s.f(s.s[i], s.s[j]) }
+func (s sliceFn(Ele)) 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 f.
+func SliceFn(type Ele)(s []Ele, f func(Ele, Ele) bool) {
+	Sort(sliceFn(Ele){s, f})
+}
+```
+
+An example of calling this might be:
+
+```Go
+	var s []*Person
+	// ...
+	sort.SliceFn(s, func(p1, p2 *Person) bool { return p1.Name < p2.Name })
+```
+
+#### map keys
+
+Here is how to get a slice of the keys of any map.
+
+```Go
+package maps
+
+contract mappable(k K, _ V) { k == k }
+
+func Keys(type K, V mappable)(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 types will be inferred.
+
+```Go
+	k := maps.Keys(map[int]int{1:2, 2:4}) // sets k to []int{1, 2} (or {2, 1})
+```
+
+#### 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.
+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.
+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
+}
+```
+
+Example calls:
+
+```Go
+	s := []int{1, 2, 3}
+	floats := slices.Map(s, func(i int) float64 { return float64(i) })
+	sum := slices.Reduce(s, 0, func(i, j int) int { return i + j })
+	evens := slices.Filter(s, func(i int) bool { return i%2 == 0 })
+```
+
+#### 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 type.
+package set
+
+contract comparable(Ele) { Ele == Ele }
+
+type Set(type Ele comparable) map[Ele]struct{}
+
+func Make(type Ele comparable)() Set(Ele) {
+	return make(Set(Ele))
+}
+
+func (s Set(Ele)) Add(v Ele) {
+	s[v] = struct{}{}
+}
+
+func (s Set(Ele)) Delete(v Ele) {
+	delete(s, v)
+}
+
+func (s Set(Ele)) Contains(v Ele) bool {
+	_, ok := s[v]
+	return ok
+}
+
+func (s Set(Ele)) Len() int {
+	return len(s)
+}
+
+func (s Set(Ele)) Iterate(f func(Ele)) {
+	for v := range s {
+		f(v)
+	}
+}
+```
+
+Example use:
+
+```Go
+	s := set.Make(int)
+	s.Add(1)
+	if s.Contains(2) { panic("unexpected 2") }
+```
+
+This example, like the sort examples above, shows how to use this
+design to provide a compile-time type-safe wrapper around an
+existing API.
+
+#### 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 easy to write.
+
+```Go
+package chans
+
+import "runtime"
+
+// 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.
+//
+// This is a convenient way to exit a goroutine sending values when
+// the receiver stops reading them.
+func Ranger(type T)() (*Sender(T), *Receiver(T)) {
+	c := make(chan T)
+	d := make(chan struct{})
+	s := &Sender(T){values: c, done: d}
+	r := &Receiver(T){values: c, done: d}
+	runtime.SetFinalizer(r, (*Receiver(T)).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:
+		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
+// indicates whether the value is valid, or whether 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.
+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 {
+	key         K
+	val         V
+	left, right *node(K, V)
+}
+
+// New returns a new map.
+func New(type K, V)(compare func(K, K) int) *Map(K, V) {
+	return &Map(K, V){compare: compare}
+}
+
+// find looks up key in the map, and returns either a pointer
+// to the node holding key, or a pointer to the location where
+// such a node would go.
+func (m *Map(K, V)) find(key K) **node(K, V) {
+	pn := &m.root
+	for *pn != nil {
+		switch cmp := m.compare(key, (*pn).key); {
+		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.
+// Returns true if this is a new key, false if already present.
+func (m *Map(K, V)) Insert(key K, val V) bool {
+	pn := m.find(key)
+	if *pn != nil {
+		(*pn).val = val
+		return false
+	}
+	*pn = &node(K, V){key: key, val: val}
+	return true
+}
+
+// Find returns the value associated with a key, or zero if not present.
+// The found result reports whether the key was found.
+func (m *Map(K, V)) Find(key K) (V, bool) {
+	pn := m.find(key)
+	if *pn == nil {
+		var zero V // see the discussion of zero values, above
+		return zero, false
+	}
+	return (*pn).val, true
+}
+
+// keyValue is a pair of key and value used when iterating.
+type keyValue(type K, V) struct {
+	key K
+	val V
+}
+
+// InOrder returns an iterator that does an in-order traversal of the map.
+func (m *Map(K, V)) InOrder() *Iterator(K, V) {
+	sender, receiver := chans.Ranger(keyValue(K, V))()
+	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(keyValue(K, V){n.key, n.val}) &&
+			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, and a boolean indicating
+// whether they are valid or whether we have reached the end.
+func (it *Iterator(K, V)) Next() (K, V, bool) {
+	keyval, ok := it.r.Next()
+	if !ok {
+		var zerok K
+		var zerov V
+		return zerok, zerov, false
+	}
+	return keyval.key, keyval.val, true
+}
+```
+
+This is what it looks like to use this package:
+
+```Go
+import "container/orderedmap"
+
+var m = orderedmap.New(string, string)(strings.Compare)
+
+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 with the signature
+
+```Go
+func Add(s, t []byte) []byte
+```
+
+that 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
+
+// Append adds values to the end of a slice, returning a new slice.
+func Append(type T)(s []T, t ...T) []T {
+	lens := len(s)
+	tot := lens + len(t)
+	if tot <= cap(s) {
+		s = s[:tot]
+	} else {
+		news := make([]T, tot, tot + tot/2)
+		copy(news, s)
+		s = news
+	}
+	copy(s[lens:tot], 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)
+	slices.Copy(s[3:], []int{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
+
+import "sync"
+
+contract comparable(v T)  {
+	v == v
+}
+
+contract cmp1(T) {
+	comparable(T) // contract embedding
+}
+
+type Metric1(type T cmp1) struct {
+	mu sync.Mutex
+	m  map[T]int
+}
+
+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[v]++
+}
+
+contract cmp2(T1, T2) {
+	comparable(T1)
+	comparable(T2)
+}
+
+type key2(type T1, T2 cmp2) struct {
+	f1 T1
+	f2 T2
+}
+
+type Metric2(type T1, T2 cmp2) struct {
+	mu sync.Mutex
+	m  map[key2(T1, T2)]int
+}
+
+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[key(T1, T2){v1, v2}]++
+}
+
+contract cmp3(T1, T2, T3) {
+	comparable(T1)
+	comparable(T2)
+	comparable(T3)
+}
+
+type key3(type T1, T2, T3 cmp3) struct {
+	f1 T1
+	f2 T2
+	f3 T3
+}
+
+type Metric3(type T1, T2, T3 cmp3) struct {
+	mu sync.Mutex
+	m  map[key3(T1, T2, T3)]int
+}
+
+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]int)
+	}
+	m[key(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 package implementation does have a certain amount of repetition
+due to the lack of support for variadic package 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 parameterized type.
+
+```Go
+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))
+		}
+		it.Next()
+	}
+	return ret
+}
+```
+
+#### context
+
+The standard "context" package provides a `Context.Value` method to
+fetch a value from a context.
+The method returns `interface{}`, so using it normally requires a type
+assertion to the correct type.
+Here is an example of how we can add type parameters to the "context"
+package to provide a type-safe wrapper around `Context.Value`.
+
+```Go
+// Key is a key that can be used with Context.Value.
+// Rather than calling Context.Value directly, use Key.Load.
+//
+// The zero value of Key is not ready for use; use NewKey.
+type Key(type V) struct {
+	name string
+}
+
+// NewKey returns a key used to store values of type V in a Context.
+// Every Key returned is unique, even if the name is reused.
+func NewKey(type V)(name string) *Key {
+	return &Key(V){name: name}
+}
+
+// WithValue returns a new context with v associated with k.
+func (k *Key(V)) WithValue(parent Context, v V) Context {
+	return WithValue(parent, k, v)
+}
+
+// Value loads the value associated with k from ctx and reports
+//whether it was successful.
+func (k *Key(V)) Value(ctx Context) (V, bool) {
+	v, present := ctx.Value(k).(V)
+	return v.(V), present
+}
+
+// String returns the name and expected value type.
+func (k *Key(V)) String() string {
+	var v V
+	return fmt.Sprintf("%s(%T)", k.name, v)
+}
+```
+
+To see how this might be used, consider the net/http package’s
+`ServerContextKey`:
+
+```Go
+var ServerContextKey = &contextKey{"http-server"}
+
+	// used as:
+	ctx := context.Value(ServerContextKey, srv)
+	s, present := ctx.Value(ServerContextKey).(*Server)
+```
+
+This could be written instead as
+
+```Go
+var ServerContextKey = context.NewKey(*Server)("http_server")
+
+	// used as:
+	ctx := ServerContextKey.WithValue(ctx, srv)
+	s, present := ServerContextKey.Value(ctx)
+```
+
+Code that uses `Key.WithValue` and `Key.Value` instead of
+`context.WithValue` and `context.Value` does not need any type
+assertions and is compile-time type-safe.
diff --git a/design/go2draft-error-handling-overview.md b/design/go2draft-error-handling-overview.md
new file mode 100644
index 0000000..3ee67fd
--- /dev/null
+++ b/design/go2draft-error-handling-overview.md
@@ -0,0 +1,412 @@
+# Error Handling — Problem Overview
+
+Russ Cox\
+August 27, 2018
+
+## Introduction
+
+This overview and the accompanying
+[detailed draft design](go2draft-error-handling.md)
+are part of a collection of [Go 2 draft design documents](go2draft.md).
+The overall goal of the Go 2 effort is to address
+the most significant ways that Go fails to scale
+to large code bases and large developer efforts.
+
+One way that Go programs fail to scale well is in the
+writing of error-checking and error-handling code.
+In general Go programs have too much code checking errors
+and not enough code handling them.
+(This will be illustrated below.)
+The draft design aims to address this problem by introducing
+lighter-weight syntax for error checks
+than the current idiomatic assignment-and-if-statement combination.
+
+As part of Go 2, we are also considering, as a separate concern,
+changes to the [semantics of error values](go2draft-error-values-overview.md),
+but this document is only about error checking and handling.
+
+## Problem
+
+To scale to large code bases, Go programs must be lightweight,
+[without undue repetition](https://www.youtube.com/watch?v=5kj5ApnhPAE),
+and also robust,
+[dealing gracefully with errors](https://www.youtube.com/watch?v=lsBF58Q-DnY)
+when they do arise.
+
+In the design of Go, we made a conscious choice
+to use explicit error results and explicit error checks.
+In contrast, C most typically uses explicit checking
+of an implicit error result, [errno](http://man7.org/linux/man-pages/man3/errno.3.html),
+while exception handling—found in many languages,
+including C++, C#, Java, and Python—represents implicit checking of implicit results.
+
+The subtleties of implicit checking are covered well in
+Raymond Chen’s pair of blog posts,
+"[Cleaner, more elegant, and wrong](https://blogs.msdn.microsoft.com/oldnewthing/20040422-00/?p=39683)" (2004),
+and "[Cleaner, more elegant, and harder to recognize](https://blogs.msdn.microsoft.com/oldnewthing/20050114-00/?p=36693)" (2005).
+In essence, because you can’t see implicit checks at all,
+it is very hard to verify by inspection that the error handling code
+correctly recovers from the state of the program at the time the check fails.
+
+For example, consider this code, written in a hypothetical dialect of Go with exceptions:
+
+	func CopyFile(src, dst string) throws error {
+		r := os.Open(src)
+		defer r.Close()
+
+		w := os.Create(dst)
+		io.Copy(w, r)
+		w.Close()
+	}
+
+It is nice, clean, elegant code.
+It is also invisibly wrong: if `io.Copy` or `w.Close` fails,
+the code does not remove the partially-written `dst` file.
+
+On the other hand, the equivalent actual Go code today would be:
+
+	func CopyFile(src, dst string) error {
+		r, err := os.Open(src)
+		if err != nil {
+			return err
+		}
+		defer r.Close()
+
+		w, err := os.Create(dst)
+		if err != nil {
+			return err
+		}
+		defer w.Close()
+
+		if _, err := io.Copy(w, r); err != nil {
+			return err
+		}
+		if err := w.Close(); err != nil {
+			return err
+		}
+	}
+
+This code is not nice, not clean, not elegant, and still wrong:
+like the previous version, it does not remove `dst` when `io.Copy` or `w.Close` fails.
+There is a plausible argument that at least a visible check
+could prompt an attentive reader to wonder about
+the appropriate error-handling response at that point in the code.
+In practice, however, error checks take up so much space
+that readers quickly learn to skip them to see the structure of the code.
+
+This code also has a second omission in its error handling.
+Functions should typically [include relevant information](https://golang.org/doc/effective_go.html#errors)
+about their arguments in their errors,
+like `os.Open` returning the name of the file being opened.
+Returning the error unmodified produces a failure
+without any information about the sequence of operations that led to the error.
+
+In short, this Go code has too much error checking
+and not enough error handling.
+A more robust version with more helpful errors would be:
+
+
+	func CopyFile(src, dst string) error {
+		r, err := os.Open(src)
+		if err != nil {
+			return fmt.Errorf("copy %s %s: %v", src, dst, err)
+		}
+		defer r.Close()
+
+		w, err := os.Create(dst)
+		if err != nil {
+			return fmt.Errorf("copy %s %s: %v", src, dst, err)
+		}
+
+		if _, err := io.Copy(w, r); err != nil {
+			w.Close()
+			os.Remove(dst)
+			return fmt.Errorf("copy %s %s: %v", src, dst, err)
+		}
+
+		if err := w.Close(); err != nil {
+			os.Remove(dst)
+			return fmt.Errorf("copy %s %s: %v", src, dst, err)
+		}
+	}
+
+Correcting these faults has only made the code more correct, not cleaner or more elegant.
+
+## Goals
+
+For Go 2, we would like to make error checks more lightweight,
+reducing the amount of Go program text dedicated to error checking.
+We also want to make it more convenient to write error handling,
+raising the likelihood that programmers will take the time to do it.
+
+Both error checks and error handling must remain explicit,
+meaning visible in the program text.
+We do not want to repeat the pitfalls of exception handling.
+
+Existing code must keep working and remain as valid as it is today.
+Any changes must interoperate with existing code.
+
+As mentioned above, it is not a goal of this draft design
+to change or augment the semantics of errors.
+For that discussion see the [error values problem overview](go2draft-error-values-overview.md).
+
+## Draft Design
+
+This section quickly summarizes the draft design,
+as a basis for high-level discussion and comparison with other approaches.
+
+The draft design introduces two new syntactic forms.
+First, it introduces a checked expression `check f(x, y, z)` or `check err`,
+marking an explicit error check.
+Second, it introduces a `handle` statement defining an error handler.
+When an error check fails, it transfers control to the innermost handler,
+which transfers control to the next handler above it,
+and so on, until a handler executes a `return` statement.
+
+For example, the corrected code above shortens to:
+
+	func CopyFile(src, dst string) error {
+		handle err {
+			return fmt.Errorf("copy %s %s: %v", src, dst, err)
+		}
+
+		r := check os.Open(src)
+		defer r.Close()
+
+		w := check os.Create(dst)
+		handle err {
+			w.Close()
+			os.Remove(dst) // (only if a check fails)
+		}
+
+		check io.Copy(w, r)
+		check w.Close()
+		return nil
+	}
+
+The `check`/`handle` combination is permitted in functions
+that do not themselves return errors.
+For example, here is a main function from a
+[useful but trivial program](https://github.com/rsc/tmp/blob/master/unhex/main.go):
+
+	func main() {
+		hex, err := ioutil.ReadAll(os.Stdin)
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		data, err := parseHexdump(string(hex))
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		os.Stdout.Write(data)
+	}
+
+It would be shorter and clearer to write instead:
+
+	func main() {
+		handle err {
+			log.Fatal(err)
+		}
+
+		hex := check ioutil.ReadAll(os.Stdin)
+		data := check parseHexdump(string(hex))
+		os.Stdout.Write(data)
+	}
+
+For details, see the [draft design](go2draft-error-handling.md).
+
+## Discussion and Open Questions
+
+These draft designs are meant only as a starting point for community discussion.
+We fully expect the details to be revised based on feedback and especially experience reports.
+This section outlines some of the questions that remain to be answered.
+
+**Check versus try**.
+The keyword `check` is a clear statement of what is being done.
+Originally we used the well-known exception keyword `try`.
+This did read well for function calls:
+
+	data := try parseHexdump(string(hex))
+
+But it did not read well for checks applied to error values:
+
+	data, err := parseHexdump(string(hex))
+	if err == ErrBadHex {
+		... special handling ...
+	}
+	try err
+
+In this case, `check err` is a clearer description than `try err`.
+Rust originally used `try!` to mark an explicit error check
+but moved to a special `?` operator instead.
+Swift also uses `try` to mark an explicit error check,
+but also `try!` and `try?`, and as part of a broader
+analogy to exception-handling that also includes `throw` and `catch`.
+
+Overall it seems that the draft design’s `check`/`handle`
+are sufficiently different from exception handling
+and from Rust and Swift to justify the clearer keyword,
+`check`, over the more familiar one, `try`.
+
+Both Rust and Swift are discussed in more detail below.
+
+**Defer**.
+The error handling is in some ways similar to [`defer`](https://golang.org/ref/spec#Defer_statements) and
+[`recover`](https://golang.org/ref/spec#Handling_panics),
+but for errors instead of panics.
+The current draft design makes error handlers chain lexically,
+while `defer` builds up a chain at runtime
+depending on what code executes.
+This difference matters for handlers (or deferred functions)
+declared in conditional bodies and loops.
+Although lexical stacking of error handlers seems like a marginally better design,
+it may be less surprising to match `defer` exactly.
+As an example where `defer`-like handling would be more convenient,
+if `CopyFile` established its destination `w` as either `os.Stdout` or the result of `os.Create`,
+then it would be helpful to be able to introduce the `os.Remove(dst)` handler conditionally.
+
+**Panics**.
+We’ve spent a while trying to harmonize error handling and panics,
+so that cleanup due to error handling need not be repeated for cleanup due to panics.
+All our attempts at unifying the two only led to more complexity.
+
+**Feedback**.
+The most useful general feedback would be examples of interesting uses
+that are enabled or disallowed by the draft design.
+We’d also welcome feedback about the points above,
+especially based on experience with complex
+or buggy error handling in real programs.
+
+We are collecting links to feedback at
+[golang.org/wiki/Go2ErrorHandlingFeedback](https://golang.org/wiki/Go2ErrorHandlingFeedback).
+
+## Designs in Other Languages
+
+The problem section above briefly discussed C and exception-based languages.
+
+Other recent language designs have also recognized
+the problems caused by exception handling’s invisible error checks,
+and those designs are worth examining in more detail.
+The Go draft design was inspired, at least in part, by each of them.
+
+## Rust
+
+Like Go, [Rust distinguishes](https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html)
+between expected errors, like "file not found", and unexpected errors,
+like accessing past the end of an array.
+Expected errors are returned explicitly
+while unexpected errors become program-ending panics.
+But Rust has little special-purpose
+language support for expected errors.
+Instead, concise handling of expected errors
+is done almost entirely by generics.
+
+In Rust, functions return single values (possibly a single tuple value),
+and a function returning a potential error returns a
+[discriminated union `Result<T, E>`](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html)
+that is either the successful result of type `T` or an error of type `E`.
+
+	enum Result<T, E> {
+		Ok(T),
+		Err(E),
+	}
+
+For example, `fs::File::Open` returns a `Result<fs::File, io::Error>`.
+The generic `Result<T, E>` type defines an
+[unwrap method](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html#shortcuts-for-panic-on-error-unwrap-and-expect)
+that turns a result into the underlying value (of type `T`)
+or else panics (if the result represents an error).
+
+If code does want to check an error instead of panicking,
+[the `?` operator](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator)
+macro-expands `use(result?)` into the Rust equivalent of this Go code:
+
+	if result.err != nil {
+		return result.err
+	}
+	use(result.value)
+
+
+The `?` operator therefore helps shorten the error checking
+and is very similar to the draft design’s `check`.
+But Rust has no equivalent of `handle`:
+the convenience of the `?` operator comes with
+the likely omission of proper handling.
+Rust’s equivalent of Go’s explicit error check `if err != nil` is
+[using a `match` statement](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html),
+which is equally verbose.
+
+Rust’s `?` operator began life as
+[the `try!` macro](https://doc.rust-lang.org/beta/book/first-edition/error-handling.html#the-real-try-macro).
+
+## Swift
+
+Swift’s `try`, `catch`, and `throw` keywords appear at first glance to be
+implementing exception handling, but really they are syntax for explicit error handling.
+
+Each function’s signature specifies whether the function
+can result in ("throw") an error.
+Here is an [example from the Swift book](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID510):
+
+	func canThrowErrors() throws -> String
+	func cannotThrowErrors() -> String
+
+These are analogous to the Go result lists `(string, error)` and `string`.
+
+Inside a "throws" function, the
+`throw` statement returns an error,
+as in this [example, again from the Swift book](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID509):
+
+	throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
+
+Every call to a "throws" function must specify at the call site
+what to do in case of error. In general that means nesting the call
+(perhaps along with other calls) inside a [do-catch block](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID541),
+with all potentially-throwing calls marked by the `try` keyword:
+
+
+	do {
+		let s = try canThrowErrors()
+		let t = cannotThrowErrors()
+		let u = try canThrowErrors() // a second call
+	} catch {
+		handle error from try above
+	}
+
+The key differences from exception handling as in C++, Java, Python,
+and similar languages are:
+
+- Every error check is marked.
+- There must be a `catch` or other direction about what to do with an error.
+- There is no implicit stack unwinding.
+
+Combined, those differences make all error checking,
+handling, and control flow transfers explicit, as in Go.
+
+Swift introduces three shorthands to avoid having
+to wrap every throwing function call in a `do`-`catch` block.
+
+First, outside a block, `try canThrowErrors()`
+[checks for the error and re-throws it](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID510),
+like Rust’s old `try!` macro and current `?` operator.
+
+Second, `try! canThrowErrors()`
+[checks for the error and turns it into a runtime assertion failure](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID513),
+like Rust’s `.unwrap` method.
+
+Third, `try? canThrowErrors()`
+[evaluates to nil on error, or else the function’s result](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID542).
+The Swift book gives this example:
+
+	func fetchData() -> Data? {
+		if let data = try? fetchDataFromDisk() { return data }
+		if let data = try? fetchDataFromServer() { return data }
+		return nil
+	}
+
+The example discards the exact reasons these functions failed.
+
+For cleanup, Swift adds lexical [`defer` blocks](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID514),
+which run when the enclosing scope is exited, whether by an explicit `return` or by throwing an error.
diff --git a/design/go2draft-error-handling.md b/design/go2draft-error-handling.md
new file mode 100644
index 0000000..b6e3016
--- /dev/null
+++ b/design/go2draft-error-handling.md
@@ -0,0 +1,660 @@
+# Error Handling — Draft Design
+
+Marcel van Lohuizen\
+August 27, 2018
+
+## Abstract
+
+We present a draft design to extend the Go language with dedicated error handling constructs.
+These constructs are in the spirit of "[errors are values](https://blog.golang.org/errors-are-values)"
+but aim to reduce the verbosity of handling errors.
+
+For more context, see the [error handling problem overview](go2draft-error-handling-overview.md).
+
+## Background
+
+There have been many proposals over time to improve error handling in Go. For instance, see:
+
+*   [golang.org/issue/21161](https://golang.org/issue/21161): simplify error handling with `|| err` suffix
+*   [golang.org/issue/18721](https://golang.org/issue/18721): add "must" operator `#` to check and return error
+*   [golang.org/issue/16225](https://golang.org/issue/16225): add functionality to remove repetitive `if err != nil` return
+*   [golang.org/issue/21182](https://golang.org/issue/21182): reduce noise in return statements that contain mostly zero values
+*   [golang.org/issue/19727](https://golang.org/issue/19727): add vet check for test of wrong `err` variable
+*   [golang.org/issue/19642](https://golang.org/issue/19642): define `_` on right-hand side of assignment as zero value
+*   [golang.org/issue/19991](https://golang.org/issue/19991): add built-in result type, like Rust, OCaml
+
+Related, but not addressed by this proposal:
+
+*   [golang.org/issue/20803](https://golang.org/issue/20803): require call results to be used or explicitly gnored
+*   [golang.org/issue/19511](https://golang.org/issue/19511): “Writing Web Applications” ignores error from `ListenAndServe`
+*   [golang.org/issue/20148](https://golang.org/issue/20148): add vet check for missing test of returned error
+
+We have also consulted the [experience reports about error handling](https://golang.org/wiki/ExperienceReports#error-handling).
+
+Many of the proposals focus on verbosity.
+both the verbosity of having to check error values
+and the verbosity of zeroing out non-error return values.
+Other proposals address issues related to correctness,
+like error variable shadowing or the relative ease with which one can forget to check an error value.
+
+This draft design incorporates many of the suggestions made in these issues.
+
+## Design
+
+This draft design builds upon the convention in Go programs
+that a function that can fail
+returns an `error` value as its final result.
+
+This draft design introduces the keywords `check` and `handle`,
+which we will introduce first by example.
+
+Today, errors are commonly handled in Go using the following pattern:
+
+	func printSum(a, b string) error {
+		x, err := strconv.Atoi(a)
+		if err != nil {
+			return err
+		}
+		y, err := strconv.Atoi(b)
+		if err != nil {
+			return err
+		}
+		fmt.Println("result:", x + y)
+		return nil
+	}
+
+With the `check`/`handle` construct, we can instead write:
+
+	func printSum(a, b string) error {
+		handle err { return err }
+		x := check strconv.Atoi(a)
+		y := check strconv.Atoi(b)
+		fmt.Println("result:", x + y)
+		return nil
+	}
+
+For each check, there is an implicit handler chain function,
+explained in more detail below.
+Here, the handler chain is the same for each check
+and is defined by the single `handle` statement to be:
+
+	func handleChain(err error) error {
+		return err
+	}
+
+The handler chain is only presented here as a function to define its semantics;
+it is likely to be implemented differently inside the Go compiler.
+
+### Checks
+
+A `check` applies to an expression of type `error`
+or a function call returning a list of values ending in
+a value of type `error`.
+If the error is non-nil.
+A `check` returns from the enclosing function
+by returning the result of invoking the handler chain
+with the error value.
+A `check` expression applied to a function call returning multiple results
+evaluates to the result of that call with the final error result removed.
+A `check` expression applied to a plain expression or to a function call returning only an error value
+cannot itself be used as a value; it can only appear as an expression statement.
+
+Given new variables `v1`, `v2`, ..., `vN`, `vErr`,
+
+	v1, ..., vN := check <expr>
+
+is equivalent to:
+
+	v1, ..., vN, vErr := <expr>
+	if vErr != nil {
+		<error result> = handlerChain(vn)
+		return
+	}
+
+where `vErr` must have type `error` and `<error result>` denotes
+the (possibly unnamed) error result from the enclosing function.
+Similarly,
+
+	foo(check <expr>)
+
+is equivalent to:
+
+	v1, ..., vN, vErr := <expr>
+	if vErr != nil {
+		<error result> = handlerChain(vn)
+		return
+	}
+	foo(v1, ..., vN)
+
+If the enclosing function has no final error result,
+a failing `check` calls `handlerChain` followed by a return.
+
+Since a `check` is an expression, we could write the `printSum` example above as:
+
+	func printSum(a, b string) error {
+		handle err { return err }
+		fmt.Println("result:", check strconv.Atoi(x) + check strconv.Atoi(y))
+		return nil
+	}
+
+For purposes of order of evaluation, `check` expressions are treated as equivalent to function calls.
+
+In general, the syntax of `check` is:
+
+	UnaryExpr  = PrimaryExpr | unary_op UnaryExpr | CheckExpr .
+	CheckExpr  = "check" UnaryExpr .
+
+It is common for idiomatic Go code to wrap the error with context information.
+Suppose our original example wrapped the error with the name of the function:
+
+	func printSum(a, b string) error {
+		x, err := strconv.Atoi(a)
+		if err != nil {
+			return fmt.Errorf("printSum(%q + %q): %v", a, b, err)
+		}
+		y, err := strconv.Atoi(b)
+		if err != nil {
+			return fmt.Errorf("printSum(%q + %q): %v", a, b, err)
+		}
+		fmt.Println("result:", x+y)
+		return nil
+	}
+
+Using a handler allows writing the wrapping just once:
+
+	func printSum(a, b string) error {
+		handle err {
+			return fmt.Errorf("printSum(%q + %q): %v", a, b, err)
+		}
+		x := check strconv.Atoi(a)
+		y := check strconv.Atoi(b)
+		fmt.Println("result:", x + y)
+		return nil
+	}
+
+It is not necessary to vary the wrapping code to determine where in `printSum` the error occurred:
+The error returned by `strconv.Atoi` will include its argument.
+This design encourages writing more idiomatic and cleaner error messages
+and is in keeping with existing Go practice, at least in the standard library.
+
+### Handlers
+
+The `handle` statement defines a block, called a _handler_, to handle an error detected by a `check`.
+A `return` statement in a handler
+causes the enclosing function to return immediately with the given return values.
+A `return` without values is only allowed if the enclosing function
+has no results or uses named results.
+In the latter case,  the function returns with the current values
+of those results.
+
+The syntax for a `handle` statement is:
+
+	Statement   = Declaration | … | DeferStmt | HandleStmt .
+	HandleStmt  = "handle" identifier Block .
+
+A _handler chain function_ takes an argument of type `error`
+and has the same result signature as the function
+for which it is defined.
+It executes all handlers in lexical scope in reverse order of declaration
+until one of them executes a `return` statement.
+The identifier used in each `handle` statement
+maps to the argument of the handler chain function.
+
+Each check may have a different handler chain function
+depending on the scope in which it is defined. For example, consider this function:
+
+    func process(user string, files chan string) (n int, err error) {
+	    handle err { return 0, fmt.Errorf("process: %v", err)  }      // handler A
+	    for i := 0; i < 3; i++ {
+	        handle err { err = fmt.Errorf("attempt %d: %v", i, err) } // handler B
+	        handle err { err = moreWrapping(err) }                    // handler C
+
+	        check do(something())  // check 1: handler chain C, B, A
+	    }
+	    check do(somethingElse())  // check 2: handler chain A
+	}
+
+Check 1, inside the loop, runs handlers C, B, and A, in that order.
+Note that because `handle` is lexically scoped,
+the handlers defined in the loop body do not accumulate
+on each new iteration, in contrast to `defer`.
+
+Check 2, at the end of the function, runs only handler A,
+no matter how many times the loop executed.
+
+It is a compile-time error for a handler chain function body to be empty:
+there must be at least one handler, which may be a default handler.
+
+As a consequence of what we have introduced so far:
+
+- There is no way to resume control in the enclosing function after `check` detects an error.
+- Any handler always executes before any deferred functions are executed.
+- If the enclosing function has result parameters, it is a compile-time error if the handler chain for any check
+  is not guaranteed to execute a `return` statement.
+
+A panic in a handler executes as if it occurred in the enclosing function.
+
+### Default handler
+
+All functions whose last result is of type `error` begin with an implicit _default handler_.
+The default handler assigns the error argument to the last result and then returns,
+using the other results unchanged.
+In functions without named results, this means using zero values for the leading results.
+In functions with named results, this means using the current values of those results.
+
+Relying on the default handler, `printSum` can be rewritten as
+
+	func printSum(a, b string) error {
+		x := check strconv.Atoi(a)
+		y := check strconv.Atoi(b)
+		fmt.Println("result:", x + y)
+		return nil
+	}
+
+The default handler eliminates one of the motivations for
+[golang.org/issue/19642](https://golang.org/issue/19642)
+(using `_` to mean a zero value, to make explicit error returns shorter).
+
+In case of named return values,
+the default handler does not guarantee the non-error return values will be zeroed:
+the user may have assigned values to them earlier.
+In this case it will still be necessary to specify the zero values explicitly,
+but at least it will only have to be done once.
+
+### Stack frame preservation
+
+Some error handling packages, like [github.com/pkg/errors](https://github.com/pkg/errors),
+decorate errors with stack traces.
+To preserve the ability to provide this information,
+a handler chain appears to the runtime
+as if it were called by the enclosing function,
+in its own stack frame.
+The `check` expression appears in the stack
+as the caller of the handler chain.
+
+There should be some helper-like mechanism to allow skipping
+over handler stack frames. This will allow code like
+
+	func TestFoo(t *testing.T) {
+		for _, tc := range testCases {
+			x, err := Foo(tc.a)
+			if err != nil {
+				t.Fatal(err)
+			}
+			y, err := Foo(tc.b)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if x != y {
+				t.Errorf("Foo(%v) != Foo(%v)", tc.a, tc.b)
+			}
+		}
+	}
+
+to be rewritten as:
+
+	func TestFoo(t *testing.T) {
+		handle err { t.Fatal(err) }
+		for _, tc := range testCases {
+			x := check Foo(tc.a)
+			y := check Foo(tc.b)
+			if x != y {
+				t.Errorf("Foo(%v) != Foo(%v)", tc.a, tc.b)
+			}
+		}
+	}
+
+while keeping the error line information useful. Perhaps it would be enough to allow:
+
+	handle err {
+		t.Helper()
+		t.Fatal(err)
+	}
+
+### Variable shadowing
+
+The use of `check` avoids repeated declaration of variables named `err`,
+which was the main motivation for
+allowing a mix of new and predeclared variables in [short variable declarations](https://golang.org/ref/spec#Short_variable_declarations) (`:=` assignments).
+Once `check` statements are available,
+there would be so little valid redeclaration remaining
+that we might be able to forbid shadowing
+and close [issue 377](https://golang.org/issue/377).
+
+### Examples
+
+A good error message includes relevant context,
+such as the function or method name and its arguments.
+Allowing handlers to chain allows adding new information as the function progresses.
+For example, consider this function:
+
+	func SortContents(w io.Writer, files []string) error {
+	    handle err {
+	        return fmt.Errorf("process: %v", err)             // handler A
+	    }
+
+	    lines := []strings{}
+	    for _, file := range files {
+	        handle err {
+	            return fmt.Errorf("read %s: %v ", file, err)  // handler B
+	        }
+	        scan := bufio.NewScanner(check os.Open(file))     // check runs B on error
+	        for scan.Scan() {
+	            lines = append(lines, scan.Text())
+	        }
+	        check scan.Err()                                  // check runs B on error
+	    }
+	    sort.Strings(lines)
+	    for _, line := range lines {
+	        check io.WriteString(w, line)                     // check runs A on error
+	    }
+	}
+
+The comments show which handlers are invoked for each of the
+`check` expressions if these were to detect an error.
+Here, only one handler is called in each case.
+If handler B did not execute in a return statement,
+it would transfer control to handler A.
+
+
+If a `handle` body does not execute an explicit `return` statement,
+the next earlier handler in lexical order runs:
+
+	type Error struct {
+		Func string
+		User string
+		Path string
+		Err  error
+	}
+
+	func (e *Error) Error() string
+
+	func ProcessFiles(user string, files chan string) error {
+		e := Error{ Func: "ProcessFile", User: user}
+		handle err { e.Err = err; return &e } // handler A
+		u := check OpenUserInfo(user)         // check 1
+		defer u.Close()
+		for file := range files {
+			handle err { e.Path = file }       // handler B
+			check process(check os.Open(file)) // check 2
+		}
+		...
+	}
+
+Here, if check 2 catches an error,
+it will execute handler B and,
+since handler B does not execute a `return` statement,
+then handler A.
+All handlers will be run before the `defer`.
+Another key difference between `defer` and `handle`:
+the second handler will be executed exactly once
+only when the second `check` fails.
+A `defer` in that same position would cause a new function call
+to be deferred until function return for every iteration.
+
+### Draft spec
+
+The syntax for a `handle` statement is:
+
+	HandleStmt  = "handle" identifier Block .
+
+It declares a _handler_, which is a block of code with access to a new identifier
+bound to a variable of type `error`.
+A `return` statement in a handler returns from the enclosing function,
+with the same semantics and restrictions as for `return` statements
+in the enclosing function itself.
+
+A _default handler_ is defined at the top of functions
+whose last return parameter is of type `error`.
+It returns the current values of all leading results
+(zero values for unnamed results), and the error value
+as its final result.
+
+A _handler chain call_ for a statement and error value executes
+all handlers in scope of that statement in reverse order in a new stack frame,
+binding their identifier to the error value.
+At least one handler must be in scope and, if the enclosing function
+has result parameters, at least one of those (possibly the default handler)
+must end with a terminating statement.
+
+The syntax of the `check` expression is:
+
+	CheckExpr    = "check" UnaryExpr .
+
+It checks whether a plain expression or a function call’s last result,
+which must be of type error, is non-nil.
+If the error result is nil, the check evaluates to all but the last value.
+If the error result is nil, the check calls its handler chain for that value
+in a new stack frame and returns the result from the enclosing function.
+
+The same rules that apply for the order of evaluation of calls in
+expressions apply to the order of evaluation of multiple checks
+appearing in a single expression.
+The `check` expression cannot be used inside handlers.
+
+## Summary
+
+*   A _handler chain_ is a function, defined within the context of an _enclosing function_, which:
+    -   takes a single argument of type `error`,
+    -   has the same return parameters as the enclosing function, and
+    -   executes one or more blocks, called _handlers_.
+*   A `handle` statement declares a handler for a handler chain and declares
+    an identifier that refers to the error argument of that handler chain.
+    -   A `return` statement in a handler causes the handler chain to stop executing
+        and the enclosing function to return using the specified return values.
+    -   If the enclosing function has named result parameters,
+        a `return` statement with an empty expression list causes the handler chain
+        to return with the current values of those arguments.
+*   The `check` expression tests whether a plain expression or a
+    function’s last result, which must be of type `error`, is non-nil.
+    -   For multi-valued expressions, `check` yields all but the last value as its result.
+    -   If `check` is applied to a single error value,
+        `check` consumes that value and doesn’t produce any result.
+        Consequently it cannot be used in an expression.
+    -   The _handler chain of a check_ is defined to execute all the handlers
+        in scope within the enclosing function in reverse order until one of them returns.
+    -   For non-nil values, `check` calls the handler chain with this value,
+        sets the return values, if any, with the results, and returns from the enclosing function.
+    -   The same rules that apply for the order of evaluation of calls in expressions
+        apply to the order of evaluation of multiple checks appearing in a single expression.
+*   A `check` expression cannot be used inside handlers.
+*   A _default handler_ is defined implicitly at the top of a function with a final result parameter
+    of type `error`.
+    -   For functions with unnamed results, the default handler returns zero values
+        for all leading results and the error value for the final result.
+    -   For functions with named results, the default handler returns the current
+        values of all leading results and the error value for the final result.
+    -   Because the default handler is declared at the top of a function,
+        it is always last in the handler chain.
+
+As a corollary of these rules:
+
+*   Because the handler chain is called like a function, the location
+    where the `check` caught an error is preserved as the handler’s caller’s frame.
+*   If the enclosing function has result parameters,
+    it is a compile-time error if at the point of any `check` expression
+    none of the handlers in scope is a
+    [terminating statement](https://golang.org/ref/spec#Terminating_statements).
+    Note that the default handler ends in a terminating statement.
+*   After a `check` detects an error, one cannot resume control of an enclosing function.
+*   If a handler executes, it is always before any `defer` defined within the same enclosing function.
+
+## Discussion
+
+One drawback of the presented design is that it introduces a context-dependent control-flow jump,
+like `break` and `continue`.
+The semantics of `handle` are similar to but the same as `defer`, adding
+another thing for developers to learn.
+We believe that the reduction in verbosity, coupled with the increased ease to wrap error messages
+as well as doing so idiomatically is worth this cost.
+
+Another drawback is that this design might appear to add exceptions to Go.
+The two biggest problems with exceptions are
+that checks are not explicitly marked and that
+the invoked handler is difficult to determine
+and may depend on the call stack.
+`Check`/`handle` has neither problem:
+checks are marked and only execute lexically scoped
+handlers in the enclosing function.
+
+## Other considerations
+
+This section discusses aspects of the design that we have discussed in the past.
+
+### Keyword: try versus check
+
+Swift and Rust define a `try` keyword which is similar to the `check` discussed
+in this design.
+Unlike `try` in Swift and Rust, check allows checking of any expression
+that is assignable to error, not just calls,
+making the use of `try` somewhat contrived.
+We could consider `try` for the sake of consistency with other languages,
+but Rust is moving away from try to the new `?` operator,
+and Swift has not just `try` but also `try!`, `try?`, `catch`, and `throw`.
+
+### Keyword: handle versus catch
+
+The keyword `handle` was chosen instead of `catch` to avoid confusion with the
+exception semantics conventionally associated with `catch`.
+Most notably, `catch` permits the surrounding function to continue,
+while a handler cannot: the function will always exit after the handler chain completes.
+All the handler chain can do is clean up and set the function results.
+
+### Checking error returns from deferred calls
+
+The presented design does not provide a mechanism for checking errors
+returned by deferred calls.
+We were unable to find a way to unify them cleanly.
+
+This code does not compile:
+
+	func Greet(w io.WriteCloser) error {
+		defer func() {
+			check w.Close()
+		}()
+		fmt.Fprintf(w, "hello, world\n")
+		return nil
+	}
+
+What the code likely intends is for the `check` to cause `Greet` to return the error,
+but the `check` is not in `Greet`.
+Instead, the `check` appears in a function literal returning no results.
+The function therefore has no default handler,
+so there is no handler chain for the `check` to call,
+which causes a compilation failure.
+
+Even with new syntax to write a deferred checked function call,
+such as `defer check w.Close()`,
+there is an ordering problem: deferred calls run
+after the function executes its `return` statement;
+in the case of an error, the handlers have already run.
+It would be surprising to run any of them a second time
+as a result of a deferred `check`.
+
+### A check-else statement
+
+A `check <expr> else <block>` statement could allow a block attached to
+a check to be executed if an error is detected.
+This would allow, for instance, setting an HTTP error code that a handler can pick up to wrap an error.
+
+Joe Duffy proposed a similar construct in his
+[Error Model](http://joeduffyblog.com/2016/02/07/the-error-model/) blog post.
+
+However, this is generally not needed for error wrapping,
+so it seems that this will not be needed much in practice.
+Nesting `check` expressions with else blocks could make code unwieldy.
+
+Analysis of a large code corpus shows that adding a `check`-`else`
+construct usually does not help much.
+Either way, the design does not preclude adding such a construct later if all else fails.
+
+Note that a `check`-`else` can already be spelled out explicitly:
+
+	x, err := <expr>
+	if err != nil {
+		<any custom handling, possibly including "check err">
+	}
+
+We can also write helpers like:
+
+	func e(err, code int, msg string) *appError {
+		if err == nil {
+			return nil
+		}
+		return &appError{err, msg, code}
+	}
+
+	check e(doX(), 404, "record not found")
+
+instead of:
+
+	if err := doX(); err != nil {
+		return &appError{err, "record not found", 404}
+	}
+
+Many wrapper functions, including `github.com/pkg/errors`'s `Wrap`,
+start with a nil check.
+We could rely on the compiler to optimize this particular case.
+
+## Considered Ideas
+
+### Using a ? operator instead of check
+
+Rust is moving to a syntax of the form `<expr>?` instead of `try! <expr>`.
+The rationale is that the `?` allows for better chaining, as in `f()?.g()?.h()`.
+In Go, control flow transfers are as a general rule accompanied by keywords
+(the exception being the boolean operators `||` and `&&`).
+We believe that deviating from this would be too inconsistent.
+
+Also, although the `?` approach may read better for chaining,
+it reads worse for passing the result of a `check` to a function.
+Compare, for instance
+
+	check io.Copy(w, check newReader(foo))
+
+to
+
+	io.Copy(w, newReader(foo)?)?
+
+Finally, handlers and `check` expressions go hand-in-hand.
+Handlers are more naturally defined with a keyword.
+It would be somewhat inconsistent
+to have the accompanying `check` construct not also use a keyword.
+
+## Comparisons
+
+### Midori
+
+Joe Duffy offers many valuable insights in the use of exceptions versus error codes
+in his [Error Model](http://joeduffyblog.com/2016/02/07/the-error-model/) blog post.
+
+### C++ proposal
+
+Herb Sutter’s [proposal for C++](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf)
+seems to come close to the what is presented here.
+Although syntax varies in several places, the basic approach of propagating errors
+as values with try and allowing handlers to deal with errors is similar.
+The catch handlers, however, discard the error by default
+unless they are rethrown in the catch block.
+There is no way to continue after an error in our design.
+The article offers interesting insights about the advantages of this approach.
+
+### Rust
+
+Rust originally defined `try!` as shorthand for checking an error
+and returning it from the enclosing function if found.
+For more complex handling, instead of handlers, Rust uses pattern matching on unwrapped return types.
+
+### Swift
+
+Swift defines a `try` keyword with somewhat similar semantics to the
+`check` keyword introduced here.
+A `try` in Swift may be accompanied by a `catch` block.
+However, unlike with `check`-`handle`,
+the `catch` block will prevent the function from returning
+unless the block explicitly rethrows the error.
+In the presented design, there is no way to stop exiting the function.
+
+Swift also has a `try!`, which panics if an error is detected,
+and a `try?`-`else`, which allows two blocks to be associated
+that respectively will be run if the `try?` checks succeeds or fails.
diff --git a/design/go2draft-error-inspection.md b/design/go2draft-error-inspection.md
new file mode 100644
index 0000000..b1bf05d
--- /dev/null
+++ b/design/go2draft-error-inspection.md
@@ -0,0 +1,282 @@
+# Error Inspection — Draft Design
+
+Jonathan Amsterdam\
+Damien Neil\
+August 27, 2018
+
+## Abstract
+
+We present a draft design that adds support for
+programmatic error handling to the standard errors package.
+The design adds an interface to standardize the
+common practice of wrapping errors.
+It then adds a pair of helper functions in [package `errors`](https://golang.org/pkg/errors),
+one for matching sentinel errors and one for matching errors by type.
+
+For more context, see the [error values problem overview](go2draft-error-values-overview.md).
+
+## Background
+
+Go promotes the idea that [errors are values](https://blog.golang.org/errors-are-values)
+and can be handled via ordinary programming.
+One part of handling errors is extracting information from them,
+so that the program can make decisions and take action.
+(The control-flow aspects of error handling are [a separate topic](go2draft-error-handling-overview.md),
+as is [formatting errors for people to read](go2draft-error-values-overview.md).)
+
+Go programmers have two main techniques for providing information in errors.
+If the intent is only to describe a unique condition with no additional data,
+a variable of type error suffices, like this one from the [`io` package](https://golang.org/pkg/io).
+
+	var ErrUnexpectedEOF = errors.New("unexpected EOF")
+
+Programs can act on such _sentinel errors_ by a simple comparison:
+
+	if err == io.ErrUnexpectedEOF { ... }
+
+To provide more information, the programmer can define a new type
+that implements the `error` interface.
+For example, `os.PathError` is a struct that includes a pathname.
+Programs can extract information from these errors by using type assertions:
+
+	if pe, ok := err.(*os.PathError); ok { ... pe.Path ... }
+
+Although a great deal of successful Go software has been written
+over the past decade with these two techniques,
+their weakness is the inability to handle the addition of new information to existing errors.
+The Go standard library offers only one tool for this, `fmt.Errorf`,
+which can be used to add textual information to an error:
+
+	if err != nil {
+		return fmt.Errorf("loading config: %v", err)
+	}
+
+But this reduces the underlying error to a string,
+easily read by people but not by programs.
+
+The natural way to add information while preserving
+the underlying error is to _wrap_ it in another error.
+The standard library already does this;
+for example, `os.PathError` has an `Err` field that contains the underlying error.
+A variety of packages outside the standard library generalize this idea,
+providing functions to wrap errors while adding information.
+(See the references below for a partial list.)
+We expect that wrapping will become more common if Go adopts
+the suggested [new error-handling control flow features](go2draft-error-handling-overview.md)
+to make it more convenient.
+
+Wrapping an error preserves its information, but at a cost.
+If a sentinel error is wrapped, then a program cannot check
+for the sentinel by a simple equality comparison.
+And if an error of some type T is wrapped (presumably in an error of a different type),
+then type-asserting the result to T will fail.
+If we encourage wrapping, we must also support alternatives to the
+two main techniques that a program can use to act on errors,
+equality checks and type assertions.
+
+## Goals
+
+Our goal is to provide a common framework so that programs can treat errors
+from different packages uniformly.
+We do not wish to replace the existing error-wrapping packages.
+We do want to make it easier and less error-prone for programs to act on errors,
+regardless of which package originated the error or how it was augmented
+on the way back to the caller.
+And of course we want to preserve the correctness
+of existing code and the ability for any package to declare a type that is an error.
+
+Our design focuses on retrieving information from errors.
+We don’t want to constrain how errors are constructed or wrapped,
+nor must we in order to achieve our goal of simple and uniform error handling by programs.
+
+## Design
+
+### The Unwrap Method
+
+The first part of the design is to add a standard, optional interface implemented by
+errors that wrap other errors:
+
+	package errors
+
+	// A Wrapper is an error implementation
+	// wrapping context around another error.
+	type Wrapper interface {
+		// Unwrap returns the next error in the error chain.
+		// If there is no next error, Unwrap returns nil.
+		Unwrap() error
+	}
+
+Programs can inspect the chain of wrapped errors
+by using a type assertion to check for the `Unwrap` method
+and then calling it.
+
+The design does not add `Unwrap` to the `error` interface itself:
+not all errors wrap another error,
+and we cannot invalidate
+existing error implementations.
+
+### The Is and As Functions
+
+Wrapping errors breaks the two common patterns for acting on errors,
+equality comparison and type assertion.
+To reestablish those operations,
+the second part of the design adds two new functions: `errors.Is`, which searches
+the error chain for a specific error value, and `errors.As`, which searches
+the chain for a specific type of error.
+
+The `errors.Is` function is used instead of a direct equality check:
+
+	// instead of err == io.ErrUnexpectedEOF
+	if errors.Is(err, io.ErrUnexpectedEOF) { ... }
+
+It follows the wrapping chain, looking for a target error:
+
+	func Is(err, target error) bool {
+		for {
+			if err == target {
+				return true
+			}
+			wrapper, ok := err.(Wrapper)
+			if !ok {
+				return false
+			}
+			err = wrapper.Unwrap()
+			if err == nil {
+				return false
+			}
+		}
+	}
+
+The `errors.As` function is used instead of a type assertion:
+
+	// instead of pe, ok := err.(*os.PathError)
+	if pe, ok := errors.As(*os.PathError)(err); ok { ... pe.Path ... }
+
+Here we are assuming the use of the [contracts draft design](go2draft-generics-overview.md)
+to make `errors.As` explicitly polymorphic:
+
+	func As(type E)(err error) (e E, ok bool) {
+		for {
+			if e, ok := err.(E); ok {
+				return e, true
+			}
+			wrapper, ok := err.(Wrapper)
+			if !ok {
+				return e, false
+			}
+			err = wrapper.Unwrap()
+			if err == nil {
+				return e, false
+			}
+		}
+	}
+
+If Go 2 does not choose to adopt polymorphism or if we need a function
+to use in the interim, we could write a temporary helper:
+
+	// instead of pe, ok := err.(*os.PathError)
+	var pe *os.PathError
+	if errors.AsValue(&pe, err) { ... pe.Path ... }
+
+It would be easy to mechanically convert this code to the polymorphic `errors.As`.
+
+## Discussion
+
+The most important constraint on the design
+is that no existing code should break.
+We intend that all the existing code in the standard library
+will continue to return unwrapped errors,
+so that equality and type assertion will behave exactly as before.
+
+Replacing equality checks with `errors.Is` and type assertions with `errors.As`
+will not change the meaning of existing programs that do not wrap errors,
+and it will future-proof programs against wrapping,
+so programmers can start using these two functions as soon as they are available.
+
+We emphasize that the goal of these functions,
+and the `errors.Wrapper` interface in particular, is to support _programs_, not _people_.
+With that in mind, we offer two guidelines:
+
+1. If your error type’s only purpose is to wrap other errors
+with additional diagnostic information,
+like text strings and code location, then don’t export it.
+That way, callers of `As` outside your package
+won’t be able to retrieve it.
+However, you should provide an `Unwrap` method that returns the wrapped error,
+so that `Is` and `As` can walk past your annotations
+to the actionable errors that may lie underneath.
+
+2. If you want programs to act on your error type but not any errors
+you’ve wrapped, then export your type and do _not_ implement `Unwrap`.
+You can still expose the information of underlying errors to people
+by implementing the `Formatter` interface described
+in the [error printing draft design](go2draft-error-values-overview.md).
+
+As an example of the second guideline, consider a configuration package
+that happens to read JSON files using the `encoding/json` package.
+Malformed JSON files will result in a `json.SyntaxError`.
+The package defines its own error type, `ConfigurationError`,
+to wrap underlying errors.
+If `ConfigurationError` provides an `Unwrap` method,
+then callers of `As` will be able to discover the `json.SyntaxError` underneath.
+If the use of a JSON is an implementation detail that the package wishes to hide,
+`ConfigurationError` should still implement `Formatter`,
+to allow multi-line formatting including the JSON error,
+but it should not implement `Unwrap`, to hide the use of JSON from programmatic inspection.
+
+We recognize that there are situations that `Is` and `As` don’t handle well.
+Sometimes callers want to perform multiple checks against the same error,
+like comparing against more than one sentinel value.
+Although these can be handled by multiple calls to `Is` or `As`,
+each call walks the chain separately, which could be wasteful.
+Sometimes, a package will provide a function to retrieve information from an unexported error type,
+as in this [old version of gRPC's status.Code function](https://github.com/grpc/grpc-go/blob/f4b523765c542aa30ca9cdb657419b2ed4c89872/status/status.go#L172).
+`Is` and `As` cannot help here at all.
+For cases like these,
+programs can traverse the error chain directly.
+
+## Alternative Design Choices
+
+Some error packages intend for programs to act on a single error (the "Cause")
+extracted from the chain of wrapped errors.
+We feel that a single error is too limited a view into the error chain.
+More than one error might be worth examining.
+The `errors.As` function can select any error from the chain;
+two calls with different types can return two different errors.
+For instance, a program could both ask whether an error is a `PathError`
+and also ask whether it is a permission error.
+
+We chose `Unwrap` instead of `Cause` as the name for the unwrapping method
+because different existing packages disagree on the meaning of `Cause`.
+A new method will allow existing packages to converge.
+Also, we’ve noticed that having both a `Cause` function and a `Cause` method
+that do different things tends to confuse people.
+
+We considered allowing errors to implement optional `Is` and `As` methods
+to allow overriding the default checks in `errors.Is` and `errors.As`.
+We omitted them from the draft design for simplicity.
+For the same reason, we decided against a design that provided a tree of underlying errors,
+despite its use in one prominent error package
+([github.com/hashicorp/errwrap](https://godoc.org/github.com/hashicorp/errwrap)).
+We also decided against explicit error hierarchies,
+as in https://github.com/spacemonkeygo/errors.
+The `errors.As` function’s ability to retrieve errors of more than one type
+from the chain provides similar functionality:
+if you want every `InvalidRowKey` error to be a `DatabaseError`, include both in the chain.
+
+## References
+
+We were influenced by several of the existing error-handling packages, notably:
+
+ - [github.com/pkg/errors](https://godoc.org/github.com/pkg/errors)
+ - [gopkg.in/errgo.v2](https://godoc.org/gopkg.in/errgo.v2)
+ - [github.com/hashicorp/errwrap](https://godoc.org/github.com/hashicorp/errwrap)
+ - [upspin.io/errors](https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html)
+ - [github.com/spacemonkeygo/errors](https://godoc.org/github.com/spacemonkeygo/errors)
+
+Some of these package would only need to add an `Unwrap` method to their wrapping error types to be compatible with this design.
+
+We also want to acknowledge Go proposals similar to ours:
+
+ - [golang.org/issue/27020](https://golang.org/issue/27020) — add a standard Causer interface for Go 2 errors
+ - [golang.org/issue/25675](https://golang.org/issue/25675) — adopt Cause and Wrap from github.com/pkg/errors
diff --git a/design/go2draft-error-printing.md b/design/go2draft-error-printing.md
new file mode 100644
index 0000000..63e0d78
--- /dev/null
+++ b/design/go2draft-error-printing.md
@@ -0,0 +1,356 @@
+# Error Printing — Draft Design
+
+Marcel van Lohuizen\
+August 27, 2018
+
+## Abstract
+
+This document is a draft design for additions to the errors package
+to define defaults for formatting error messages,
+with the aim of making formatting of different error message implementations interoperable.
+This includes the printing of detailed information,
+stack traces or other position information, localization, and limitations of ordering.
+
+For more context, see the [error values problem overview](go2draft-error-values-overview.md).
+
+## Background
+
+It is common in Go to build your own error type.
+Applications can define their own local types or use
+one of the many packages that are available for defining errors.
+
+Broadly speaking, errors serve several audiences:
+programs, users, and diagnosers.
+Programs may need to make decisions based on the value of errors.
+This need is addressed in [the error values draft designs](go2draft-error-values-overview.md).
+Users need a general idea of what went wrong.
+Diagnosers may require more detailed information.
+This draft design focuses on providing legible error printing
+to be read by people—users and diagnosers—not programs.
+
+When wrapping one error in context to produce a new error,
+some error packages distinguish between opaque and transparent
+wrappings, which affect whether error inspection is allowed to
+see the original error.
+This is a valid distinction.
+Even if the original error is hidden from programs, however,
+it should typically still be shown to people.
+Error printing therefore must use an interface method
+distinct from the common “next in error chain” methods
+like `Cause`, `Reason`, or the error inspection draft design’s `Unwrap`.
+
+There are several packages that have attempted to provide common error interfaces.
+These packages typically do not interoperate well with each other or with bespoke error implementations.
+Although the interfaces they define are similar, there are implicit assumptions that lead to poor interoperability.
+
+## Design
+
+This design focuses on printing errors legibly, for people to read.
+This includes possible stack trace information,
+a consistent ordering,
+and consistent handling of formatting verbs.
+
+### Error detail
+
+The design allows for an error message to include additional detail
+printed upon request, by using special formatting verb `%+v`.
+This detail may include stack traces or other detailed information
+that would be reasonable to elide in a shorter display.
+Of course, many existing error implementations only have
+a short display, and we don’t expect them to change.
+But implementations that do track additional detail
+will now have a standard way to present it.
+
+### Printing API
+
+The error printing API should allow
+
+- consistent formatting and ordering,
+- detailed information that is only printed when requested (such as stack traces),
+- defining a chain of errors (possibly different from "reasons" or a programmatic chain),
+- localization of error messages, and
+- a formatting method that is easy for new error implementations to implement.
+
+The design presented here introduces two interfaces
+to satisfy these requirements: `Formatter` and `Printer`,
+both defined in the [`errors` package](https://golang.org/pkg/errors).
+
+An error that wants to provide additional detail implements the
+`errors.Formatter` interface’s `Format` method.
+
+The `Format` method is passed an `errors.Printer`,
+which itself has `Print` and `Printf` methods.
+
+	package errors
+
+	// A Formatter formats error messages.
+	type Formatter interface {
+		// Format is implemented by errors to print a single error message.
+		// It should return the next error in the error chain, if any.
+		Format(p Printer) (next error)
+	}
+
+	// A Printer creates formatted error messages. It enforces that
+	// detailed information is written last.
+	//
+	// Printer is implemented by fmt. Localization packages may provide
+	// their own implementation to support localized error messages
+	// (see for instance golang.org/x/text/message).
+	type Printer interface {
+		// Print appends args to the message output.
+		// String arguments are not localized, even within a localized context.
+		Print(args ...interface{})
+
+		// Printf writes a formatted string.
+		Printf(format string, args ...interface{})
+
+		// Detail reports whether error detail is requested.
+		// After the first call to Detail, all text written to the Printer
+		// is formatted as additional detail, or ignored when
+		// detail has not been requested.
+		// If Detail returns false, the caller can avoid printing the detail at all.
+		Detail() bool
+	}
+
+The `Printer` interface is designed to allow localization.
+The `Printer` implementation will typically be supplied by the
+[`fmt` package](https://golang.org/pkg/fmt)
+but can also be provided by localization frameworks such as
+[`golang.org/x/text/message`](https://golang.org/x/text/message).
+If instead a `Formatter` wrote to an `io.Writer`,
+localization with such packages would not be possible.
+
+In this example, `myAddrError` implements `Formatter`:
+Example:
+
+	type myAddrError struct {
+		address string
+		detail  string
+		err     error
+	}
+
+	func (e *myAddrError) Error() string {
+		return fmt.Sprint(e) // delegate to Format
+	}
+
+	func (e *myAddrError) Format(p errors.Printer) error {
+		p.Printf("address %s", e.address)
+		if p.Detail() {
+			p.Print(e.detail)
+		}
+		return e.err
+	}
+
+This design assumes that the
+[`fmt` package](https://golang.org/pkg/fmt)
+and localization frameworks will add code to recognize
+errors that additionally implement `Formatter`
+and use that method for `%+v`.
+These packages already recognize `error`; recognizing `Formatter` is only a little more work.
+
+Advantages of this API:
+
+- This API clearly distinguishes informative detail from a causal error chain, giving less rise to confusion.
+- Consistency between different error implementations:
+  - interpretation of formatting flags
+  - ordering of the error chain
+  - formatting and indentation
+- Less boilerplate for custom error types to implement:
+  - only one interface to implement besides error
+  - no need to implement `fmt.Formatter`.
+- Flexible: no assumption about the kind of detail information an error implementation might want to print.
+- Localizable: packages like golang.org/x/text/message can provide their own implementation of `errors.Printer` to allow translation of messages.
+- Detail information is more verbose and somewhat discouraged.
+- Performance: a single buffer can be used to print an error.
+- Users can implement `errors.Printer` to produce formats.
+
+### Format
+
+Consider an error that returned by `foo` calling `bar` calling `baz`. An idiomatic Go error string would be:
+
+	foo: bar(nameserver 139): baz flopped
+
+We suggest the following format for messages with diagnostics detail,
+assuming that each layer of wrapping adds additional diagnostics information.
+
+	foo:
+	    file.go:123 main.main+0x123
+	--- bar(nameserver 139):
+	    some detail only text
+	    file.go:456
+	--- baz flopped:
+	    file.go:789
+
+This output is somewhat akin to that of subtests.
+The first message is printed as formatted,
+but with the detail indented with 4 spaces.
+All subsequent messages are indented 4 spaces
+and prefixed with `---` and a space at the start of the message.
+
+Indenting the detail of the first message
+avoids ambiguity when multiple multiline errors
+are printed one after the other.
+
+### Formatting verbs
+
+Today, `fmt.Printf` already prints errors using these verbs:
+
+- `%s`: `err.Error()` as a string
+- `%q`: `err.Error()` as a quoted string
+- `%+q`: `err.Error()` as an ASCII-only quoted string
+- `%v`: `err.Error()` as a string
+- `%#v`: `err` as a Go value, in Go syntax
+
+This design defines `%+v` to print the error in the detailed, multi-line format.
+
+### Interaction with source line information
+
+The following API shows how printing stack traces,
+either top of the stack or full stacks per error,
+could interoperate with this package
+(only showing the parts of the API relevant to this discussion).
+
+	package errstack
+
+	type Stack struct { ... }
+
+	// Format writes the stack information to p, but only
+	// if detailed printing is requested.
+	func (s *Stack) Format(p errors.Printer) {
+		if p.Detail() {
+			p.Printf(...)
+		}
+	}
+
+This package would be used by adding a `Stack` to each error implementation
+that wanted to record one:
+
+	import ".../errstack"
+
+	type myError struct {
+		msg        string
+		stack      errstack.Stack
+		underlying error
+	}
+
+	func (e *myError) Format(p errors.Printer) error {
+		p.Printf(e.msg)
+		e.stack.Format(p)
+		return e.underlying
+	}
+
+	func newError(msg string, underlying error) error {
+		return &myError{
+			msg:   msg,
+			stack: errstack.New(),
+		}
+	}
+
+### Localized errors
+
+The [`golang.org/x/text/message` package](https://golang.org/x/text/message)
+currently has its own
+implementation of `fmt`-style formatting.
+It would need to recognize `errors.Formatter` and
+provide its own implementation of `errors.Printer`
+with a translating `Printf` and localizing `Print`.
+
+	import "golang.org/x/text/message"
+
+	p := message.NewPrinter(language.Dutch)
+	p.Printf("Error: %v", err)
+
+Any error passed to `%v` that implements `errors.Formatter`
+would use the localization machinery.
+Only format strings passed to `Printf` would be translated,
+although all values would be localized.
+Alternatively, since errors are always text,
+we could attempt to translate any error message,
+or at least to have `gotext` do static analysis
+similarly to what it does now for regular Go code.
+
+To facilitate localization, `golang.org/x/text/message` could implement
+an `Errorf` equivalent which delays the substitution of arguments
+until it is printed so that it can be properly localized.
+
+The `gotext` tool would have to be modified
+to extract error string formats from code.
+It should be easy to modify the analysis to pick up static error messages
+or error messages that are formatted using an `errors.Printer`'s `Printf` method.
+However, calls to `fmt.Errorf` will be problematic,
+as it substitutes the arguments prematurely.
+We may be able to change `fmt.Errorf` to evaluate and save its arguments
+but delay the final formatting.
+
+### Error trees
+
+So far we have assumed that there is a single chain of errors.
+To implement formatting a tree of errors, an error list type
+could print itself as a new error chain,
+returning this single error with the entire chain as detail.
+Error list types occur fairly frequently,
+so it may be beneficial to standardize on an error list type to ensure consistency.
+
+The default output might look something like this:
+
+	foo: bar: baz flopped (and 2 more errors)
+
+The detailed listing would show all the errors:
+
+	foo:
+	--- multiple errors:
+	    bar1
+	    --- baz flopped
+	    bar2
+	    bar3
+
+## Alternate designs
+
+We considered defining multiple optional methods,
+to provide fine-grained information such as the underlying error, detailed message, etc.
+This had many drawbacks:
+
+- Implementations needed to implement `fmt.Formatter` to correctly handle print verbs,
+  which was cumbersome and led to inconsistencies and incompatibilities.
+- It required having two different methods returning the “next error” in the wrapping chain:
+  one to report the next for error inspection and one to report the next for printing.
+  It was difficult to remember which was which.
+- Error implementations needed too many methods.
+- Most such approaches were incompatible with localization.
+
+We also considered hiding the `Formatter` interface in the `fmt.State` implementation.
+This was clumsy to implement and it shared the drawback of requiring error implementation authors
+to understand how to implement all the relevant formatting verbs.
+
+## Migration
+
+Packages that currently do their own formatting will have to be rewritten
+to use the new interfaces to maximize their utility.
+In experimental conversions of
+[`github.com/pkg/errors`](https://godoc.org/github.com/pkg/errors),
+[`gopkg.in/errgo.v2`](https://godoc.org/gopkg.in/errgo.v2),
+and
+[`upspin.io/errors`](https://upspin.io/errors),
+we found that implementing `Formatter` simplified printing logic considerably,
+with the simultaneous benefit of making chains of these errors
+interoperable.
+
+This design’s detailed, multiline form is always an expansion of the single-line form,
+proceeding through in the same order, outermost to innermost.
+Other packages, like [`github.com/pkg/errors`](https://godoc.org/github.com/pkg/errors),
+conventionally print detailed errors in the opposite order, contradicting the single-line form.
+Users used to reading those errors will need to learn to read the new format.
+
+## Disadvantages
+
+The approach presented here does not provide any standard to programmatically
+extract the information that is to be displayed in the messages.
+It seems, though, there is no need for this.
+The goal of this approach is interoperability and standardization, not providing structured access.
+
+As noted in the previous section, existing error packages that
+print detail will need to update their formatting implementations,
+and some will find that the reporting order of errors has changed.
+
+This approach does not specify a standard for printing trees.
+Providing a standard error list type could help with this.
diff --git a/design/go2draft-error-values-overview.md b/design/go2draft-error-values-overview.md
new file mode 100644
index 0000000..7570ca9
--- /dev/null
+++ b/design/go2draft-error-values-overview.md
@@ -0,0 +1,490 @@
+# Error Values — Problem Overview
+
+Russ Cox\
+August 27, 2018
+
+## Introduction
+
+This overview and the accompanying
+detailed draft designs
+are part of a collection of [Go 2 draft design documents](go2draft.md).
+The overall goal of the Go 2 effort is to address
+the most significant ways that Go fails to scale
+to large code bases and large developer efforts.
+
+One way that Go programs fail to scale well is in the capability of typical errors.
+A variety of popular helper packages add functionality
+beyond the standard error interface,
+but they do so in incompatible ways.
+As part of Go 2, we are considering whether to standardize any
+"optional interfaces" for errors,
+to allow helper packages to interoperate
+and ideally to reduce the need for them.
+
+As part of Go 2, we are also considering,
+as a separate concern,
+more convenient [syntax for error checks and handling](go2draft-error-handling-overview.md).
+
+## Problem
+
+Large programs must be able to test for
+and react to errors programmatically and also report them well.
+
+Because an error value is any value implementing the [`error` interface](https://golang.org/ref/spec#Errors),
+there are four ways that Go programs conventionally test for specific errors.
+First, programs can test for equality with sentinel errors like `io.EOF`.
+Second, programs can check for an error implementation type using a [type assertion](https://golang.org/ref/spec#Type_assertions) or [type switch](https://golang.org/ref/spec#Type_switches).
+Third, ad-hoc checks like
+[`os.IsNotExist`](https://golang.org/pkg/os/#IsNotExist)
+check for a specific kind of error,
+doing limited unwrapping.
+Fourth, because neither of these approaches works in general when the error has been wrapped in additional context,
+programs often do substring searches in the error text reported by `err.Error()`.
+Obviously this last approach is the least desirable,
+and it would be better to support the first three checks even in the presence of arbitrary wrapping.
+
+The most common kind of wrapping is use of fmt.Errorf, as in
+
+	if err != nil {
+		return fmt.Errorf("write users database: %v", err)
+	}
+
+Wrapping in an error type is more work but more useful for programmatic tests, like in:
+
+	if err != nil {
+		return &WriteError{Database: "users", Err: err}
+	}
+
+Either way, if the original `err` is a known sentinel or known error implementation type,
+then wrapping, whether by `fmt.Errorf` or a new type like `WriteError`,
+breaks both equality checks and type assertions looking for the original error.
+This discourages wrapping, leading to less useful errors.
+
+In a complex program, the most useful description of an error
+would include information about all the different operations leading to the error.
+For example, suppose that the error writing to the database
+earlier was due to an RPC call.
+Its implementation called `net.Dial` of `"myserver"`,
+which in turn read `/etc/resolv.conf`, which maybe today was accidentally unreadable.
+The resulting error’s `Error` method might return this string (split onto two lines for this document):
+
+	write users database: call myserver.Method: \
+	    dial myserver:3333: open /etc/resolv.conf: permission denied
+
+The implementation of this error is five different levels (four wrappings):
+
+  1. A `WriteError`, which provides `"write users database: "` and wraps
+  2. an `RPCError`, which provides `"call myserver.Method: "` and wraps
+  3. a `net.OpError`, which provides `"dial myserver:3333: "` and wraps
+  4. an `os.PathError`, which provides `"open /etc/resolv.conf: "` and wraps
+  5. `syscall.EPERM`, which provides `"permission denied"`
+
+There are many questions you might want to ask programmatically of err,
+including:
+(i) is it an RPCError?
+(ii) is it a net.OpError?
+(iii) does it satisfy the net.Error interface?
+(iv) is it an os.PathError?
+(v) is it a permission error?
+
+The first problem is that it is too hard to ask these kinds of questions.
+The functions [`os.IsExist`](https://golang.org/pkg/os/#IsExist),
+[`os.IsNotExist`](https://golang.org/pkg/os/#IsNotExist),
+[`os.IsPermission`](https://golang.org/pkg/os/#IsPermission),
+and
+[`os.IsTimeout`](https://golang.org/pkg/os/#IsTimeout)
+are symptomatic of the problem.
+They lack generality in two different ways:
+first, each function tests for only one specific kind of error,
+and second, each understands only a very limited number of wrapping types.
+In particular, these functions understand a few wrapping errors,
+notably [`os.PathError`](https://golang.org/pkg/os/#PathError), but
+not custom implementations like our hypothetical `WriteError`.
+
+The second problem is less critical but still important:
+the reporting of deeply nested errors is too difficult to read
+and leaves no room for additional detail,
+like relevant file positions in the program.
+
+Popular helper packages exist to address these problems,
+but they disagree on the solutions and in general do not interoperate.
+
+## Goals
+
+There are two goals, corresponding to the two main problems.
+First, we want to make error inspection by programs easier
+and less error-prone, to improve the error handling and
+robustness of real programs.
+Second, we want to make it possible to print errors
+with additional detail, in a standard form.
+
+Any solutions must keep existing code working
+and fit with existing source trees.
+In particular, the concepts of comparing for equality with error sentinels
+like `io.ErrUnexpectedEOF` and testing for errors of a particular type must be preserved.
+Existing error sentinels must continue to be supported,
+and existing code will not change to return different error types.
+That said, it would be okay to expand functions like
+[`os.IsPermission`](https://golang.org/pkg/os/#IsPermission) to understand arbitrary wrappings instead of a fixed set.
+
+When considering solutions for printing additional error detail,
+we prefer solutions that make it possible—or at least avoid making it impossible—to
+localize and translate errors using
+[golang.org/x/text/message](https://godoc.org/golang.org/x/text/message).
+
+Packages must continue to be able to define their own error types easily.
+It would be unacceptable to define a new, generalized "one true error implementation"
+and require all code to use that implementation.
+It would be equally unacceptable to add so many additional requirements
+on error implementations that only a few packages would bother.
+
+Errors must also remain efficient to create.
+Errors are not exceptional.
+It is common for errors to be generated, handled, and discarded,
+over and over again, as a program executes.
+
+As a cautionary tale, years ago at Google a program written
+in an exception-based language was found to be spending
+all its time generating exceptions.
+It turned out that a function on a deeply-nested stack was
+attempting to open each of a fixed list of file paths,
+to find a configuration file.
+Each failed open operation threw an exception;
+the generation of that exception spent a lot of time recording
+the very deep execution stack;
+and then the caller discarded all that work and continued around its loop.
+The generation of an error in Go code must remain a fixed cost,
+regardless of stack depth or other context.
+(In a panic, deferred handlers run _before_ stack unwinding
+for the same reason: so that handlers that do care about
+the stack context can inspect the live stack,
+without an expensive snapshot operation.)
+
+## Draft Design
+
+The two main problems—error inspection and error formatting—are
+addressed by different draft designs.
+The constraints of keeping interoperation with existing code
+and allowing packages to continue to define their own error types
+point strongly in the direction of defining
+optional interfaces that an error implementation can satisfy.
+Each of the two draft designs adds one such interface.
+
+### Error inspection
+
+For error inspection, the draft design follows the lead of existing packages
+like [github.com/pkg/errors](https://github.com/pkg/errors)
+and defines an optional interface for an error to return the next error
+in the chain of error wrappings:
+
+	package errors
+
+	type Wrapper interface {
+		Unwrap() error
+	}
+
+For example, our hypothetical `WriteError` above would need to implement:
+
+	func (e *WriteError) Unwrap() error { return e.Err }
+
+Using this method, the draft design adds two new functions to package errors:
+
+	// Is reports whether err or any of the errors in its chain is equal to target.
+	func Is(err, target error) bool
+
+	// As checks whether err or any of the errors in its chain is a value of type E.
+	// If so, it returns the discovered value of type E, with ok set to true.
+	// If not, it returns the zero value of type E, with ok set to false.
+	func As(type E)(err error) (e E, ok bool)
+
+Note that the second function has a type parameter, using the
+[contracts draft design](go2draft-generics-overview.md).
+Both functions would be implemented as a loop first testing
+`err`, then `err.Unwrap()`, and so on, to the end of the chain.
+
+Existing checks would be rewritten as needed to be "wrapping-aware":
+
+	errors.Is(err, io.ErrUnexpectedEOF)     // was err == io.ErrUnexpectedEOF
+	pe, ok := errors.As(*os.PathError)(err) // was pe, ok := err.(*os.PathError)
+
+For details, see the [error inspection draft design](go2draft-error-inspection.md).
+
+### Error formatting
+
+For error formatting, the draft design defines an optional interface implemented by errors:
+
+	package errors
+
+	type Formatter interface {
+		Format(p Printer) (next error)
+	}
+
+The argument to `Format` is a `Printer`, provided by the package formatting the error
+(usually [`fmt`](https://golang.org/pkg/fmt), but possibly a localization package like
+[`golang.org/x/text/message`](https://godoc.org/golang.org/x/text/message) instead).
+The `Printer` provides methods `Print` and `Printf`, which emit output,
+and `Detail`, which reports whether extra detail should be printed.
+
+The `fmt` package would be adjusted to format errors printed using `%+v` in a multiline format,
+with additional detail.
+
+For example, our database `WriteError` might implement the new `Format` method and the old `Error` method as:
+
+	func (e *WriteError) Format(p errors.Printer) (next error) {
+		p.Printf("write %s database", e.Database)
+		if p.Detail() {
+			p.Printf("more detail here")
+		}
+		return e.Err
+	}
+
+	func (e *WriteError) Error() string { return fmt.Sprint(e) }
+
+And then printing the original database error using `%+v` would look like:
+
+
+	write users database:
+	    more detail here
+	--- call myserver.Method:
+	--- dial myserver:3333:
+	--- open /etc/resolv.conf:
+	--- permission denied
+
+The errors package might also provide a convenient implementation
+for recording the line number of the code creating the error and printing it back when `p.Detail` returns true.
+If all the wrappings involved included that line number information, the `%+v` output would look like:
+
+	write users database:
+	    more detail here
+	    /path/to/database.go:111
+	--- call myserver.Method:
+	    /path/to/grpc.go:222
+	--- dial myserver:3333:
+	    /path/to/net/dial.go:333
+	--- open /etc/resolv.conf:
+	    /path/to/os/open.go:444
+	--- permission denied
+
+For details, see the [error printing draft design](go2draft-error-printing.md).
+
+## Discussion and Open Questions
+
+These draft designs are meant only as a starting point for community discussion.
+We fully expect the details to be revised based on feedback and especially experience reports.
+This section outlines some of the questions that remain to be answered.
+
+**fmt.Errorf**.
+If `fmt.Errorf` is invoked with a format ending in `": %v"` or `": %s"`
+and with a final argument implementing the error interface,
+then `fmt.Errorf` could return a special implementation
+that implements both `Wrapper` and `Formatter`.
+Should it? We think definitely yes to `Formatter`.
+Perhaps also yes to `Wrapper`, or perhaps we should
+introduce `fmt.WrapErrorf`.
+
+Adapting `fmt.Errorf` would make nearly all existing code
+using `fmt.Errorf` play nicely with `errors.Is`, `errors.As`,
+and multiline error formatting.
+Not adapting `fmt.Errorf` would instead require adding
+some other API that did play nicely,
+for use when only textual context needs to be added.
+
+**Source lines**.
+Many error implementations will want to record source lines
+to be printed as part of error detail.
+We should probably provide some kind of embedding helper
+in [package `errors`](https://golang.org/pkg/errors)
+and then also use that helper in `fmt.Errorf`.
+Another question is whether `fmt.Errorf` should by default
+record the file and line number of its caller, for display in the
+detailed error format.
+
+Microbenchmarks suggest that recording the caller’s file and line
+number for printing in detailed displays would roughly double the
+cost of `fmt.Errorf`, from about 250ns to about 500ns.
+
+**Is versus Last**.
+Instead of defining `errors.Is`,
+we could define a function `errors.Last`
+that returns the final error in the chain.
+Then code would write `errors.Last(err) == io.ErrUnexpectedEOF`
+instead of `errors.Is(err, io.ErrUnexpectedEOF)`
+
+The draft design avoids this approach for a few reasons.
+First, `errors.Is` seems a clearer statement of intent.
+Second, the higher-level `errors.Is` leaves room for future adaptation,
+instead of being locked into the single equality check.
+Even today, the draft design’s implementation tests for equality with each error in the chain,
+which would allow testing for a sentinel value
+that was itself a wrapper (presumably of another sentinel)
+as opposed to only testing the end of the error chain.
+A possible future expansion might be to allow individual error implementations
+to define their own optional `Is(error) bool` methods
+and have `errors.Is` prefer that method over the default equality check.
+In contrast, using the lower-level idiom
+`errors.Last(err) == io.ErrUnexpectedEOF`
+eliminates all these possibilities.
+
+Providing `errors.Last(err)` might also encourage type checks
+against the result, instead of using `errors.As`.
+Those type checks would of course not test against
+any of the wrapper types, producing a different result and
+introducing confusion.
+
+**Unwrap**. It is unclear if `Unwrap` is the right name for the method
+returning the next error in the error chain.
+Dave Cheney’s [`github.com/pkg/errors`](https://golang.org/pkg/errors) has popularized `Cause` for the method name,
+but it also uses `Cause` for the function that returns the last error in the chain.
+At least a few people we talked to
+did not at first understand the subtle semantic difference between method and function.
+An early draft of our design used `Next`, but all our explanations
+referred to wrapping and unwrapping,
+so we changed the method name to match.
+
+**Feedback**. The most useful general feedback would be
+examples of interesting uses that are enabled or disallowed
+by the draft design.
+We’d also welcome feedback about the points above,
+especially based on experience
+with complex or buggy error inspection or printing in real programs.
+
+We are collecting links to feedback at
+[golang.org/wiki/Go2ErrorValuesFeedback](https://golang.org/wiki/Go2ErrorValuesFeedback).
+
+## Other Go Designs
+
+### Prehistoric Go
+
+The original representation of an error in Go was `*os.Error`, a pointer to this struct:
+
+	// Error is a structure wrapping a string describing an error.
+	// Errors are singleton structures, created by NewError, so their addresses can
+	// be compared to test for equality. A nil Error pointer means ``no error''.
+	// Use the String() method to get the contents; it handles the nil case.
+	// The Error type is intended for use by any package that wishes to define
+	// error strings.
+	type Error struct {
+		s string
+	}
+
+	func NewError(s string) *Error
+
+In April 2009, we changed `os.Error` to be an interface:
+
+	// An Error can represent any printable error condition.
+	type Error interface {
+		String() string
+	}
+
+This was the definition of errors in the initial public release,
+and programmers learned to use equality tests and type checks to inspect them.
+
+In November 2011, as part of the lead-up to Go 1,
+and in response to feedback from Roger Peppe and others in the Go community,
+we lifted the interface out of the standard library and into [the language itself](https://golang.org/ref/spec#Errors),
+producing the now-ubiquitous error interface:
+
+	type error interface {
+		Error() string
+	}
+
+The names changed but the basic operations remained the name: equality tests and type checks.
+
+### github.com/spacemonkeygo/errors
+
+[github.com/spacemonkeygo/errors](https://godoc.org/github.com/spacemonkeygo/errors) (July 2013)
+was written to support
+[porting a large Python codebase to Go](https://medium.com/space-monkey-engineering/go-space-monkey-5f43744bffaa).
+It provides error class hierarchies, automatic logging and stack traces, and arbitrary associated key-value pairs.
+
+For error inspection,
+it can test whether an error belongs to a particular class, optionally considering wrapped errors,
+and considering entire hierarchies.
+
+The `Error` type’s `Error` method returns a string giving the error class name,
+message, stack trace if present, and other data.
+There is also a `Message` method that returns just the message,
+but there is no support for custom formatting.
+
+### github.com/juju/errgo
+
+[github.com/juju/errgo](https://github.com/juju/errgo) (February 2014)
+was written to support Juju, a large Go program developed at Canonical.
+When you wrap an error, you can choose whether to
+adopt the cause of an underlying error or hide it.
+Either way the underlying error is available to printing routines.
+
+The package’s `Cause` helper function returns an error intended for the program to act upon,
+but it only unwraps one layer,
+in contrast to
+[`github.com/pkg/errors`](https://godoc.org/github.com/pkg/errors)'s `Cause`
+function, which returns the final error in the chain.
+
+The custom error implementation’s `Error` method concatenates the messages of the errors
+along the wrapping chain.
+There is also a `Details` function that returns a JSON-like string
+with both messages and location information.
+
+### gopkg.in/errgo.v1 and gopkg.in/errgo.v2
+
+[`gopkg.in/errgo.v1`](https://godoc.org/gopkg.in/errgo.v1) (July 2014)
+is a slight variation of `github.com/juju/errgo`.
+[`gopkg.in/errgo.v2`](https://godoc.org/gopkg.in/errgo.v2)
+has the same concepts but a simpler API.
+
+### github.com/hashicorp/errwrap
+
+[`github.com/hashicorp/errwrap`](https://godoc.org/github.com/hashicorp/errwrap) (October 2014)
+allows wrapping more than one error, resulting in a general tree of errors.
+It has a general `Walk` method that invokes a function on every error in the tree,
+as well as convenience functions for matching by type and message string.
+It provides no special support for displaying error details.
+
+### github.com/pkg/errors
+
+[`github.com/pkg/errors`](https://godoc.org/github.com/pkg/errors) (December 2015)
+provides error wrapping and stack trace capture.
+It introduced `%+v` to format errors with additional detail.
+The package assumes that only the last error of the chain is of interest,
+so it provides a helper `errors.Cause` to retrieve that last error.
+It does not provide any functions that consider the entire chain when looking for a match.
+
+### upspin.io/error
+
+[`upspin.io/errors`](https://godoc.org/upspin.io/errors)
+is an error package customized for [Upspin](https://upspin.io),
+documented in Rob Pike and Andrew Gerrand’s December 2017 blog post
+“[Error handling in Upspin](https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html).”
+
+This package is a good reminder of the impact that a custom errors package
+can have on a project, and that it must remain easy to implement bespoke
+error implementations.
+It introduced the idea of `errors.Is`, although the one in the draft design
+differs in detail from Upspin’s.
+We considered for a while whether it was possible to adopt
+something like Upspin’s `errors.Match`, perhaps even to generalize
+both the draft design’s `errors.Is` and `errors.As` into a single
+primitive `errors.Match`.
+In the end we could not.
+
+## Designs in Other Languages
+
+Most languages do not allow entirely user-defined error implementations.
+Instead they define an exception base class that users extend;
+the base class provides a common place to hang functionality
+and would enable answering these questions in quite a different way.
+But of course Go has no inheritance or base classes.
+
+Rust is similar to Go in that it defines an error as anything
+implementing a particular interface.
+In Rust, that interface is three methods:
+`Display` `fmt`, to print the display form of the error;
+`Debug` `fmt`, to print the debug form of the error,
+typically a dump of the data structure itself,
+and `cause`, which returns the “lower-level cause of this error,”
+analogous to `Unwrap`.
+
+Rust does not appear to provide analogues to the draft design’s
+`errors.Is` or `errors.As`, or any other helpers that walk the
+error cause chain.
+Of course, in Rust, the `cause` method is required, not optional.
diff --git a/design/go2draft-generics-overview.md b/design/go2draft-generics-overview.md
new file mode 100644
index 0000000..cad240d
--- /dev/null
+++ b/design/go2draft-generics-overview.md
@@ -0,0 +1,1016 @@
+# Generics — Problem Overview
+
+Russ Cox\
+August 27, 2018
+
+## Introduction
+
+This overview and the accompanying
+[detailed draft design](go2draft-contracts.md)
+are part of a collection of [Go 2 draft design documents](go2draft.md).
+The overall goal of the Go 2 effort is to address
+the most significant ways that Go fails to scale
+to large code bases and large developer efforts.
+
+The Go team, and in particular Ian Lance Taylor,
+has been investigating and discussing possible designs for "generics"
+(that is, parametric polymorphism; see note below)
+since before Go’s first open source release.
+We understood from experience with C++ and Java
+that the topic was rich and complex and would take
+a long time to understand well enough to design a good solution.
+Instead of attempting that at the start,
+we spent our time on features more directly applicable to Go’s initial target
+of networked system software (now "cloud software"),
+such as concurrency, scalable builds, and low-latency garbage collection.
+
+After the release of Go 1, we continued to explore various possible
+designs for generics, and in April 2016 we
+[released those early designs](https://go.googlesource.com/proposal/+/master/design/15292-generics.md#),
+discussed in detail below.
+As part of re-entering "design mode" for the Go 2 effort, we are again
+attempting to find a design for generics that we feel fits well into
+the language while providing enough of the flexibility and
+expressivity that users want.
+
+Some form of generics was one of the top two requested features in both the
+[2016](https://blog.golang.org/survey2016-results) and
+[2017](https://blog.golang.org/survey2017-results)
+Go user surveys (the other was package management).
+The Go community maintains a
+"[Summary of Go Generics Discussions](https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/view#heading=h.vuko0u3txoew)"
+document.
+
+Many people have concluded (incorrectly) that the Go team’s position
+is "Go will never have generics." On the contrary, we understand the
+potential generics have, both to make Go far more flexible and
+powerful and to make Go far more complicated.
+If we are to add generics, we want to do it in a way that gets as much
+flexibility and power with as little added complexity as possible.
+
+_Note on terminology_: Generalization based on type parameters was
+called parametric polymorphism when it was
+[first identified in 1967](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.332.3161&rep=rep1&type=pdf)
+and for decades thereafter in the functional programming community.
+The [GJ proposal](http://homepages.inf.ed.ac.uk/wadler/papers/gj-oopsla/gj-oopsla-letter.pdf),
+which led to adding parametric polymorphism in Java 5, changed the
+terminology first to "genericity" and eventually to "generics".
+All imperative languages since Java that have added support for
+parametric polymorphism have called it "generics." We make no
+distinction between the terms, but it is important to emphasize that
+"generics" means more than just generic data containers.
+
+## Problem
+
+To scale Go to large code bases and developer efforts, it is important that code reuse work well.
+Indeed, one early focus for Go was simply to make sure that programs consisting of many independent packages built quickly, so that code reuse was not too expensive.
+One of Go’s key distinguishing features is its approach to interfaces, which are also targeted directly at code reuse.
+Specifically, interfaces make it possible to write abstract implementations of algorithms that elide unnecessary detail.
+For example,
+[container/heap](https://godoc.org/container/heap)
+provides heap-maintenance algorithms as ordinary functions that operate on a
+[heap.Interface](https://godoc.org/container/heap#Interface),
+making them applicable to any backing storage, not just a slice of values.
+This can be very powerful.
+
+At the same time, most programmers who want a priority queue
+don’t want to implement the underlying storage for it and then invoke the heap algorithms.
+They would prefer to let the implementation manage its own array,
+but Go does not permit expressing that in a type-safe way.
+The closest one can come is to make a priority queue of `interface{}` values
+and use type assertions after fetching each element.
+(The standard [`container/list`](https://golang.org/pkg/container/list)
+and [`container/ring`](https://golang.org/pkg/container/ring) implementations take this approach.)
+
+Polymorphic programming is about more than data containers.
+There are many general algorithms we might want to implement
+as plain functions that would apply to a variety of types,
+but every function we write in Go today must apply to only a single type.
+Examples of generic functions we’d like to write include:
+
+	// Keys returns the keys from a map.
+	func Keys(m map[K]V) []K
+
+	// Uniq filters repeated elements from a channel,
+	// returning a channel of the filtered data.
+	func Uniq(<-chan T) <-chan T
+
+	// Merge merges all data received on any of the channels,
+	// returning a channel of the merged data.
+	func Merge(chans ...<-chan T) <-chan T
+
+	// SortSlice sorts a slice of data using the given comparison function.
+	func SortSlice(data []T, less func(x, y T) bool)
+
+[Doug McIlroy has suggested](https://golang.org/issue/26282) that Go add two new
+channel primitives `splice` and `clone`.
+These could be implemented as polymorphic functions instead.
+
+The
+"[Go should have generics](https://go.googlesource.com/proposal/+/master/design/15292-generics.md#)" proposal
+and the "[Summary of Go Generics Discussions](https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/view#heading=h.vuko0u3txoew)"
+contain additional discussion of the problem.
+
+## Goals
+
+Our goal is to address the problem of writing Go libraries that
+abstract away needless type detail, such as the examples in the
+previous section, by allowing parametric polymorphism with type
+parameters.
+
+In particular, in addition to the expected container types, we aim to
+make it possible to write useful libraries for manipulating arbitrary
+map and channel values, and ideally to write polymorphic functions
+that can operate on both `[]byte` and `string` values.
+
+It is not a goal to enable other kinds of parameterization, such as
+parameterization by constant values.
+It is also not a goal to enable specialized implementations of
+polymorphic definitions, such as defining a general `vector<T>` and a
+special-case `vector<bool>` using bit-packing.
+
+We want to learn from and avoid the problems that generics have caused
+for C++ and in Java (described in detail in the section about other
+languages, below).
+
+To support
+[software engineering over time](https://research.swtch.com/vgo-eng),
+generics for Go must record constraints on type parameters explicitly,
+to serve as a clear, enforced agreement between caller and
+implementation.
+It is also critical that the compiler report clear errors when a
+caller does not meet those constraints or an implementation exceeds
+them.
+
+Polymorphism in Go must fit smoothly into the surrounding language,
+without awkward special cases and without exposing implementation
+details.
+For example, it would not be acceptable to limit type parameters to
+those whose machine representation is a single pointer or single word.
+As another example, once the general `Keys(map[K]V) []K` function
+contemplated above has been instantiated with `K` = `int` and `V` = `string`,
+it must be treated semantically as equivalent to a hand-written
+non-generic function.
+In particular it must be assignable to a variable of type `func(map[int]string) []int`.
+
+Polymorphism in Go should be implementable both at compile time (by
+repeated specialized compilation, as in C++) and at run time, so that
+the decision about implementation strategy can be left as a decision
+for the compiler and treated like any other compiler optimization.
+This flexibility would address the
+[generic dilemma](https://research.swtch.com/generic) we’ve discussed
+in the past.
+
+Go is in large part a language that is straightforward and
+understandable for its users.
+If we add polymorphism, we must preserve that.
+
+## Draft Design
+
+This section quickly summarizes the draft design, as a basis for
+high-level discussion and comparison with other approaches.
+
+The draft design adds a new syntax for introducing a type parameter
+list in a type or function declaration: `(type` <_list of type names_>`)`.
+For example:
+
+	type List(type T) []T
+
+	func Keys(type K, V)(m map[K]V) []K
+
+Uses of a parameterized declaration supply the type arguments using ordinary call syntax:
+
+	var ints List(int)
+
+	keys := Keys(int, string)(map[int]string{1:"one", 2: "two"})
+
+The generalizations in these examples require nothing of the types `T`,
+`K`, and `V`: any type will do.
+In general an implementation may need to constrain the possible types
+that can be used.
+For example, we might want to define a `Set(T)`, implemented as a list
+or map, in which case values of type `T` must be able to be compared for
+equality.
+To express that, the draft design introduces the idea of a named
+**_contract_**.
+A contract is like a function body illustrating the operations the
+type must support.
+For example, to declare that values of type `T` must be comparable:
+
+	contract Equal(t T) {
+		t == t
+	}
+
+To require a contract, we give its name after the list of type parameters:
+
+	type Set(type T Equal) []T
+
+	// Find returns the index of x in the set s,
+	// or -1 if x is not contained in s.
+	func (s Set(T)) Find(x T) int {
+		for i, v := range s {
+			if v == x {
+				return i
+			}
+		}
+		return -1
+	}
+
+As another example, here is a generalized `Sum` function:
+
+	contract Addable(t T) {
+		t + t
+	}
+
+	func Sum(type T Addable)(x []T) T {
+		var total T
+		for _, v := range x {
+			total += v
+		}
+		return total
+	}
+
+Generalized functions are invoked with type arguments
+to select a specialized function and then invoked again with their value arguments:
+
+	var x []int
+	total := Sum(int)(x)
+
+As you might expect, the two invocations can be split:
+
+	var x []int
+	intSum := Sum(int) // intSum has type func([]int) int
+	total := intSum(x)
+
+The call with type arguments can be omitted, leaving only the call with values,
+when the necessary type arguments can be inferred from the values:
+
+	var x []int
+	total := Sum(x) // shorthand for Sum(int)(x)
+
+More than one type parameter is also allowed in types, functions, and contracts:
+
+	contract Graph(n Node, e Edge) {
+		var edges []Edge = n.Edges()
+		var nodes []Node = e.Nodes()
+	}
+
+	func ShortestPath(type N, E Graph)(src, dst N) []E
+
+The contract is applied by default to the list of type parameters, so that `(type T Equal)` is shorthand for `(type T Equal(T))`,
+and `(type N, E Graph)` is shorthand for `(type N, E Graph(N, E))`.
+
+For details, see the [draft design](go2draft-contracts.md).
+
+## Discussion and Open Questions
+
+This draft design is meant only as a starting point for community discussion.
+We fully expect the details to be revised based on feedback and especially experience reports.
+This section outlines some of the questions that remain to be answered.
+
+Our previous four designs for generics in Go all had significant problems, which we identified very quickly.
+The current draft design appears to avoid the problems in the earlier ones: we’ve spent about half a year discussing and refining it so far and still believe it could work.
+While we are not formally proposing it today, we think it is at least a good enough starting point for a community discussion with the potential to lead to a formal proposal.
+
+Even after six months of (not full time) discussion, the design is still in its earliest stages.
+We have written a parser but no type checker and no implementation.
+It will be revised as we learn more about it.
+Here we identify a few important things we are unsure about, but there are certainly more.
+
+**Implied constraints**.
+One of the examples above applies to maps of arbitrary key and value type:
+
+	func Keys(type K, V)(m map[K]V) []K {
+		...
+	}
+
+But not all types can be used as key types,
+so this function should more precisely be written as:
+
+	func Keys(type K, V Equal(K))(m map[K]V) []K {
+		...
+	}
+
+It is unclear whether that precision about
+`K` should be required of the user or inferred
+from the use of `map[K]V` in the function signature.
+
+**Dual implementation**.
+We are hopeful that the draft design satisfies the
+"dual-implementation" constraint mentioned above,
+that every parameterized type or function can be implemented
+either by compile-time or run-time type substitution,
+so that the decision becomes purely a compiler optimization, not one of semantic significance.
+But we have not yet confirmed that.
+
+One consequence of the dual-implementation constraint
+is that we have not included support for type parameters in method declarations.
+The most common place where these arise is in modeling functional operations on general containers.
+It is tempting to allow:
+
+	// A Set is a set of values of type T.
+	type Set(type T) ...
+
+	// Apply applies the function f to each value in the set s,
+	// returning a set of the results.
+	func (s Set(T)) Apply(type U)(f func(T) U) Set(U)  // NOT ALLOWED!
+
+The problem here is that a value of type `Set(int)`
+would require an infinite number of `Apply` methods to be available at runtime,
+one for every possible type `U`, all discoverable by reflection and type assertions.
+They could not all be compiled ahead of time.
+An earlier version of the design allowed generic methods but then disallowed their visibility in reflection and interface satisfaction, to avoid forcing the run-time implementation of generics.
+Disallowing generalized methods entirely seemed cleaner than allowing them with these awkward special cases.
+Note that it is still possible to write `Apply` as a top-level function:
+
+	func Apply(type T, U)(s Set(T), f func(T) U) Set(U)
+
+Working within the intersection of compile-time and run-time implementations also requires being able to reject parameterized functions or types that cause generation of an arbitrary (or perhaps just very large) number of additional types.
+For example, here are a few unfortunate programs:
+
+	// OK
+	type List(type T) struct {
+		elem T
+		next *List(T)
+	}
+
+	// NOT OK - Implies an infinite sequence of types as you follow .next pointers.
+	type Infinite(type T) struct {
+		next *Infinite(Infinite(T))
+	}
+
+	// BigArray(T)(n) returns a nil n-dimensional slice of T.
+	// BigArray(int)(1) returns []int
+	// BigArray(int)(2) returns [][]int
+	// ...
+	func BigArray(type T)(n int) interface{} {
+		if n <= 1 || n >= 1000000000 {
+			return []T(nil)
+		}
+		return BigArray([]T)(n-1)
+	}
+
+It is unclear what the algorithm is for deciding which programs to accept and which to reject.
+
+**Contract bodies**.
+Contracts are meant to look like little functions.
+They use a subset of function body syntax,
+but the actual syntax is much more limited than just "any Go code" (see the full design for details).
+We would like to understand better if it is feasible to allow any valid function body as a contract body.
+The hard part is defining precisely which generic function bodies are allowed by a given contract body.
+
+There are parallels with the C++ concepts design (discussed in detail below): the definition of a C++ concept started out being exactly a function body illustrating the necessary requirements, but over time the design changed to use a more limited list of requirements of a specific form.
+Clearly it was not workable in C++ to support arbitrary function bodies.
+But Go is a simpler language than C++ and it may be possible here.
+We would like to explore whether it is possible to implement contract body syntax as exactly function body syntax and whether that would be simpler for users to understand.
+
+**Feedback**.
+The most useful general feedback would be examples of interesting uses that are enabled or disallowed by the draft design.
+We’d also welcome feedback about the points above, especially based on experience type-checking or implementing generics in other languages.
+
+We are most uncertain about exactly what to allow in contract bodies, to make them as easy to read and write for users while still being sure the compiler can enforce them as limits on the implementation.
+That is, we are unsure about the exact algorithm to deduce the properties required for type-checking a generic function from a corresponding contract.
+After that we are unsure about the details of a run-time-based (as opposed to compile-time-based) implementation.
+
+Feedback on semantics and implementation details is far more useful and important than feedback about syntax.
+
+We are collecting links to feedback at
+[golang.org/wiki/Go2GenericsFeedback](https://golang.org/wiki/Go2GenericsFeedback).
+
+## Designs in Other Languages
+
+It is worth comparing the draft design with those in real-world use, either now or in the past.
+We are not fluent programmers in many of these languages.
+This is our best attempt to piece together the history, including links to references, but we would welcome corrections about the syntax, semantics, or history of any of these.
+
+The discussion of other language designs in this section focuses on the specification of type constraints and also implementation details and problems, because those ended up being the two most difficult parts of the Go draft design for us to work out.
+They are likely the two most difficult parts of any design for parametric polymorphism.
+In retrospect, we were biased too much by experience with C++ without concepts and Java generics. We would have been well-served to spend more time with CLU and C++ concepts earlier.
+
+We’ll use the `Set`, `Sum`, and `ShortestPath` examples above as points of comparison throughout this section.
+
+### ML, 1975
+
+ML was the first typed language to incorporate polymorphism.
+
+Christopher Strachey is usually given credit for introducing the term parametric polymorphism in his 1967 survey, "[Fundamental Concepts in Programming Languages](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.332.3161&rep=rep1&type=pdf)."
+
+Robin Milner’s 1978 paper "[A Theory of Type Polymorphism in Programming](https://courses.engr.illinois.edu/cs421/sp2013/project/milner-polymorphism.pdf)" introduced an algorithm to infer the most general types of polymorphic function bodies, instead of forcing the use of concrete types.
+Milner had already implemented his algorithm for the ML language as part of the Edinburgh LCF system.
+He wanted to be able to write the kinds of general functions possible in LISP, but in a typed language.
+
+ML inferred constraints and for that matter the types themselves from the untyped function body.
+But the inference was limited - there were no objects, classes, methods, or operators, just values (including function values).
+There was not even equality checking.
+
+Milner
+[suggested adding "equality types"](http://www.lfcs.inf.ed.ac.uk/reports/87/ECS-LFCS-87-33/ECS-LFCS-87-33.pdf) in 1987, distinguishing a type variable with no constraints (`'t`) from a type variable that must represent a type allowing equality checks (`''t`).
+
+The
+[Standard ML of New Jersey compiler](https://www.cs.princeton.edu/research/techreps/TR-097-87) (1987) implements polymorphic functions by arranging that every value is
+[represented as a single machine word](https://www.cs.princeton.edu/research/techreps/TR-142-88).
+That uniformity of representation, combined with the near-complete lack of type constraints, made it possible to use one compiled body for all invocations.
+Of course, boxing has its own allocation time and space overheads.
+
+The
+[MLton whole-program optimizing compiler](http://mlton.org/History) (1997) specializes polymorphic functions at compile time.
+
+### CLU, 1977
+
+The research language CLU, developed by Barbara Liskov’s group at MIT, was the first to introduce what we would now recognize as modern generics.
+(CLU also introduced iterators and abstract data types.)
+
+[CLU circa 1975](http://csg.csail.mit.edu/CSGArchives/memos/Memo-112-1.pdf) allowed defining parameterized types without constraints, much like in ML.
+To enable implementing a generic set despite the lack of constraints, all types were required to implement an equal method.
+
+By 1977,
+[CLU had introduced "where clauses"](https://web.eecs.umich.edu/~weimerw/2008-615/reading/liskov-clu-abstraction.pdf) to constrain parameterized types, allowing the set implementation to make its need for `equal` explicit.
+CLU also had operator methods, so that `x == y` was syntactic sugar for `t$equal(x, y)` where `t` is the type of both `x` and `y`.
+
+	set = cluster [t: type] is create, member, size, insert, delete, elements
+	        where t has equal: proctype (t, t) returns (bool)
+	    rep = array[t]
+	    % implementation of methods here, using == on values of type t
+	end set
+
+The more complex graph example is still simple in CLU:
+
+	shortestpath = proc[node, edge: type] (src, dst: node) returns array[edge]
+	        where node has edges: proctype(node) returns array[edge],
+	              edge has nodes: proctype(edge) returns array[node]
+	    ...
+	end shortestpath
+
+The 1978 paper "[Aspects of Implementing CLU](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.3516&rep=rep1&type=pdf)" discusses the compile-time versus run-time implementations of parameterized generics and details CLU's run-time-only approach.
+The "BigArray" function shown earlier is also taken from this paper (translated to Go, of course).
+
+All the ingredients for modern generics are here: syntax for declaring generalized types and functions, syntax for invoking them, a simple constraint syntax, and a well thought-out implementation.
+There was no inference of type parameters.
+The CLU designers found it helpful to see all substitutions made explicitly.
+
+In her 1992 retrospective  "[A History of CLU](http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=F5D7C821199F22C5D30A51F155DB9D23?doi=10.1.1.46.9499&rep=rep1&type=pdf)," Liskov observed, "CLU was way ahead of its time in its solution for parameterized modules.
+Even today, most languages do not support parametric polymorphism, although there is growing recognition of the need for it."
+
+### Ada, 1983
+
+Ada clearly lifted many ideas from CLU, including the approach for exceptions and parametric polymorphism, although not the elegant syntax.
+Here is an example generic squaring function from the
+[Ada 1983 spec](https://swtch.com/ada-mil-std-1815a.pdf), assembled from pages 197, 202, and 204 of the PDF.
+The generic declaration introduces a parameterized "unit" and then the function declaration appears to come separately:
+
+	generic
+		type ITEM Is private;
+		with function "*"(U, V ITEM) return ITEM is <>;
+	function SQUARING(X : ITEM) return ITEM;
+
+	function SQUARING(X : ITEM) return ITEM is
+	begin
+		return X*X;
+	end;
+
+Interestingly, this definition introduces a function SQUARING parameterized by both the type ITEM and the * operation.
+If instantiated using type INTEGER, the * operation is taken from that type:
+
+	function SQUARE is new SQUARING (INTEGER);
+
+But the * operation can also be substituted directly, allowing definition of a matrix squarer using the MATRIX-PRODUCT function.
+These two instantiations are equivalent:
+
+	function SQUARE is new SQUARING (ITEM -> MATRIX, "*'" => MATRIX-PRODUCT);
+	function SQUARE is new SQUARING (MATRIX, MATRIX-PRODUCT);
+
+We have not looked into how Ada generics were implemented.
+
+The initial Ada design contest
+[ran from 1975-1980 or so](https://www.red-gate.com/simple-talk/opinion/geek-of-the-week/tucker-taft-geek-of-the-week/), resulting eventually in the Ada 83 standard in 1983.
+We are not sure exactly when generics were added.
+
+### C++, 1991
+
+[C++ introduced templates](http://www.stroustrup.com/hopl-almost-final.pdf) in 1991, in the Cfront 3.0 release.
+The implementation was always by compile-time macro expansion, and there were no "where clauses" or other explicit constraints.
+
+	template<typename T>
+
+	class Set {
+		...
+		void Add(T item) {
+			...
+		}
+	};
+
+	template<typename T>
+	T Sum(x vector<T>) {
+		T s;
+		for(int i = 0; i < x.size(); i++) {
+			s += x[i];
+		}
+		return s;
+	}
+
+Instead, if a template was invoked with an inappropriate type, such as a Sum<char*>, the compiler reported a type-checking error in the middle of the invoked function’s body.
+This was not terribly user-friendly and soured many developers on the idea of parametric polymorphism.
+The lack of type constraints enabled the creation of the STL and transformed C++ into a wholly different language than it had been.
+Then the problem became how to add explicit type constraints sufficiently expressive to allow all the tricks used in the STL.
+
+Programmers worked around the lack of constraints by establishing conventions for expressing them.
+Stroustrup’s 1994 book
+[The Design and Evolution of C++](http://www.stroustrup.com/dne.html) gives some examples.
+The first option is to define constraints as classes:
+
+	template <class T> class Comparable {
+		T& operator=(const T&);
+		int operator==(const T&, const T&);
+		int operator<=(const T&, const T&);
+		int operator<(const T&, const T&);
+	};
+	template <class T : Comparable>
+		class vector {
+			// ...
+		};
+
+Unfortunately, this requires the original type `T` to explicitly derive from `Comparable`.
+Instead, Stroustrup suggested writing a function, conventionally named `constraints`, illustrating the requirements:
+
+	template<class T> class X {
+		// ...
+		void constraints(T* tp)
+		{	             // T must have:
+			B* bp = tp;  //   an accessible base B
+			tp->f();     //   a member function f
+			T a(l);      //   a constructor from int
+			a = *tp;     //   assignment
+			// ...
+		}
+	};
+
+Compiler errors would at least be simple, targeted, and reported as a problem with `X<T>::constraints`.
+Of course, nothing checked that other templates used only the features of T illustrated in the constraints.
+
+In 2003, Stroustrup proposed formalizing this convention as
+[C++ concepts](http://www.stroustrup.com/N1522-concept-criteria.pdf).
+The feature was intended for C++0x (eventually C++11 (2011)) but
+[removed in 2009](http://www.drdobbs.com/cpp/the-c0x-remove-concepts-decision/218600111).
+Concepts were published as a
+[separate ISO standard in 2015](https://www.iso.org/standard/64031.html), shipped in GCC, and were intended for C++17 (2017)
+[but removed in 2016](http://honermann.net/blog/2016/03/06/why-concepts-didnt-make-cxx17/).
+They are now intended for C++20 (2020).
+
+The 2003 proposal gives this syntax:
+
+	concept Element {
+		constraints(Element e1, Element e2) {
+			bool b = e1<e2;  // Elements can be compared using <
+			swap(e1,e2);     // Elements can be swapped
+		}
+	};
+
+By 2015, the syntax had changed a bit but the underlying idea was still the same.
+Stroustrup’s 2015 paper "[Concepts: The Future of Generic Programming, or How to design good concepts and use them well](http://www.stroustrup.com/good_concepts.pdf)" presents as an example a concept for having equality checking.
+(In C++, `==` and `!=` are unrelated operations so both must be specified.)
+
+	template<typename T>
+	concept bool Equality_comparable =
+	requires (T a, T b) {
+		{ a == b } -> bool; // compare Ts with ==
+		{ a != b } -> bool; // compare Ts with !=
+	};
+
+A requires expression evaluates to true if each of the listed requirements is satisfied, false otherwise.
+Thus `Equality_comparable<T>` is a boolean constant whose value depends on `T`.
+
+Having defined the predicate, we can define our parameterized set:
+
+	template<Equality_comparable T>
+	class Set {
+		...
+	};
+
+	Set<int> set;
+	set.Add(1);
+
+Here the `<Equality_comparable T>` introduces a type variable `T` with the constraint that `Equality_comparable<T> == true`.
+The class declaration above is shorthand for:
+
+	template<typename T>
+		requires Equality_comparable<T>
+	class Set {
+		...
+	};
+
+By allowing a single concept to constrain a group of related types, the C++ concept proposal makes it easy to define our shortest path example:
+
+	template<typename Node, typename Edge>
+	concept bool Graph =
+		requires(Node n, Edge e) {
+			{ n.Edges() } -> vector<Edge>;
+			{ e.Nodes() } -> vector<Node>;
+		};
+
+	template<typename Node, Edge>
+		requires Graph(Node, Edge)
+	vector<Edge> ShortestPath(Node src, Node dst) {
+		...
+	}
+
+### Java, 1997-2004
+
+In 1997, Martin Odersky and Philip Wadler introduced
+[Pizza](http://pizzacompiler.sourceforge.net/doc/pizza-language-spec.pdf), a strict superset of Java, compiled to Java bytecodes, adding three features from functional programming: parametric polymorphism, higher-order functions, and algebraic data types.
+
+In 1998, Odersky and Wadler, now joined by Gilad Bracha and David Stoutamire, introduced
+[GJ](http://homepages.inf.ed.ac.uk/wadler/papers/gj-oopsla/gj-oopsla-letter.pdf), a Pizza-derived Java superset targeted solely at parametric polymorphism, now called generics.
+The GJ design was adopted with minor changes in Java 5, released in 2004.
+
+As seen in the example, this design uses interfaces to express type constraints, with the result that parameterized interfaces must be used to create common self-referential constraints such as having an equal method that checks two items of the same type for equality.
+In CLU this constraint was written directly:
+
+	set = cluster[t: type] ...
+	        where t has equal: proctype(t, t) returns bool
+
+ In Java 5, the same constraint is written indirectly, by first defining `Equal<T>`:
+
+	interface Equal<T> {
+		boolean equal(T o);
+	}
+
+Then the constraint is `T implements Equal<T>` as in:
+
+	class Set<T implements Equal<T>> {
+		...
+		public void add(T o) {
+			...
+		}
+	}
+
+	Set<int> set;
+	set.add(1);
+
+This is Java’s variant of the C++ "[curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)" and is a common source of confusion (or at least rote memorization) among Java programmers first learning generics.
+
+The graph example is even more complex:
+
+	interface Node<Edge> {
+		List<Edge> Edges()
+	}
+
+	interface Edge<Node> {
+		List<Node> Nodes()
+	}
+
+	class ShortestPath<N implements Node<E>, E implements Edge<N>> {
+		static public List<Edge> Find(Node src, dst) {
+			...
+		}
+	}
+
+Java 4 and earlier had provided untyped, heterogeneous container classes like `List` and `Set` that used the non-specific element type `Object`.
+Java 5 generics aimed to provide type parameterization for those legacy containers.
+The originals became `List<Object>` and `Set<Object>`, but now programmers could also write `List<String>`, `List<Set<String>>`, and so on.
+
+The implementation was by "type erasure," converting to the original untyped containers, so that at runtime there were only the unparameterized implementations `List` and `Set` (of `Object`).
+
+Because the implementation needed to be memory-compatible with `List<Object>`, which is to say a list of pointers, Java value types like `int` and `boolean` could not be used as type parameters: no `List<int>`.
+Instead there is `List<Integer>`, in which each element becomes an class object instead of a plain `int`, with all the associated memory and allocation overhead.
+
+Because of the erasure, reflection on these values, including dynamic type checks using `instanceof`, has no information about the expected type of elements.
+Reflection and code written using untyped collections like `List` or `Set` therefore served as back doors to bypass the new type system.
+The inability to use `instanceof` with generics introduced other rough edges, such as not being able to define parameterized exception classes, or more precisely being able to throw an instance of a parameterized class but not catch one.
+
+Angelika Langer has written an
+[extensive FAQ](http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html), the size of which gives a sense of the complexity of Java generics.
+
+Java 10 may add runtime access to type parameter information.
+
+Experience watching the Java generics story unfold, combined with discussions with some of the main players, was the primary reason we avoided tackling any sort of generics in the first version of Go.
+Since much of the complexity arose from the design being boxed in by pre-existing container types, we mostly avoided adding container types to the standard library ([`container/list`](https://golang.org/pkg/container/list)
+and [`container/ring`](https://golang.org/pkg/container/ring) are the exceptions, but they are not widely used).
+
+Many developers associate Java generics first with the complexity around container types.
+That complexity, combined with the fact that Java lacks the concept of a plain function (such as `Sum`) as opposed to methods bound to a class, led to the common belief that generics means parameterized data structures, or containers, ignoring parameterized functions.
+This is particularly ironic given the original inspiration from functional programming.
+
+### C#, 1999-2005
+
+C#, and more broadly the .NET Common Language Runtime (CLR), added
+[support for generics](https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx) in C# 2.0, released in 2005 and the culmination of
+[research beginning in 1999](http://mattwarren.org/2018/03/02/How-generics-were-added-to-.NET/).
+
+The syntax and definition of type constraints mostly follows Java’s, using parameterized interfaces.
+
+Learning from the Java generics implementation experience, C# removes many of the rough edges.
+It makes parameterization information available at runtime, so that reflection can distinguish `List<string>` from `List<List<string>>`.
+It also allows parameterization to use basic types like int, so that `List<int>` is valid and efficient.
+
+### D, 2002
+
+D
+[added templates in D 0.40](https://wiki.dlang.org/Language_History_and_Future), released in September 2002.
+We have not tracked down the original design to see how similar it was to the current templates.
+The current D template mechanism allows parameterizing a block of arbitrary code:
+
+	template Template(T1, T2) {
+		... code using T1, T2 ...
+	}
+
+The block is instantiated using `Template!` followed by actual types, as in `Template!(int, float64)`.
+It appears that instantiation is always at compile-time, like in C++.
+If a template contains a single declaration of the same name, the usage is shortened:
+
+	template Sum(T) {
+		T Sum(T[] x) {
+			...
+		}
+	}
+
+	int[] x = ...
+	int sum = Sum!(int)(x) // short for Sum!(int).Sum(x)
+
+This code compiles and runs, but it can be made clearer by adding an
+[explicit constraint on `T`](https://dlang.org/concepts.html) to say that it must support equality:
+
+	template hasEquals(T) {
+		const hasEquals = __traits(compiles, (T t) {
+			return t == t;
+		});
+	}
+
+	template Sum(T) if (hasEquals!(T)) {
+		T Sum(T []x) {
+			...
+		}
+	}
+
+The `__traits(compiles, ...)` construct is a variant of the C++ concepts idea (see C++ discussion above).
+
+As in C++, because the constraints can be applied to a group of types, defining `Graph` does not require mutually-recursive gymnastics:
+
+	template isGraph(Node, Edge) {
+		const isGraph = __traits(compiles, (Node n, Edge e) {
+			Edge[] edges = n.Edges();
+			Node[] nodes = e.Nodes();
+		});
+	}
+
+	template ShortestPath(Node, Edge)
+			if (isGraph!(Node, Edge)) {
+		Edge[] ShortestPath(Node src, Node dst) {
+			...
+		}
+	}
+
+### Rust, 2012
+
+Rust
+[included generics in version 0.1](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-01--2012-01-20), released in 2012.
+
+Rust defines generics with syntax similar to C#, using traits (Rust’s interfaces) as type constraints.
+
+Rust avoids Java’s and C#'s curiously-recurring interface pattern for direct self-reference by introducing a `Self` type.
+For example, the protocol for having an `Equals` method can be written:
+
+	pub trait Equals {
+		fn eq(&self, other: &Self) -> bool;
+		fn ne(&self, other: &Self) -> bool;
+	}
+
+(In Rust, `&self` denotes the method's receiver variable, written without an explicit type; elsewhere in the function signature, `&Self` can be used to denote the receiver type.)
+
+And then our `Set` type can be written:
+
+	struct Set<T: Equals> {
+		...
+	}
+
+This is shorthand for
+
+	struct Set<T> where T: Equals {
+		...
+	}
+
+The graph example still needs explicitly mutually-recursive traits:
+
+	pub trait Node<Edge> {
+		fn edges(&self) -> Vec<Edge>;
+	}
+	pub trait Edge<Node> {
+		fn nodes(&self) -> Vec<Node>;
+	}
+
+	pub fn shortest_path<N, E>(src: N, dst: N) -> Vec<E>
+			where N: Node<E>, E: Edge<N> {
+		...
+	}
+
+In keeping with its "no runtime" philosophy, Rust implements generics by compile-time expansion, like C++ templates.
+
+### Swift, 2017
+
+Swift added generics in Swift 4, released in 2017.
+
+The
+[Swift language guide](https://docs.swift.org/swift-book/LanguageGuide/Generics.html) gives an example of sequential search through an array, which requires that the type parameter `T` support equality checking. (This is a popular example; it dates back to CLU.)
+
+	func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {
+		for (index, value) in array.enumerated() {
+			if value == valueToFind {
+				return index
+			}
+		}
+		return nil
+	}
+
+Declaring that `T` satisfies the
+[`Equatable`](https://developer.apple.com/documentation/swift/equatable) protocol makes the use of `==` in the function body valid.
+`Equatable` appears to be a built-in in Swift, not possible to define otherwise.
+
+Like Rust, Swift avoids Java’s and C#'s curiously recurring interface pattern for direct self-reference by introducing a `Self` type.
+For example, the protocol for having an `Equals` method is:
+
+	protocol EqualsMethod {
+		func Equals(other: Self) -> Bool
+	}
+
+Protocols cannot be parameterized, but declaring "associated types" can be used for the same effect:
+
+	protocol Node {
+		associatedtype Edge;
+		func Edges() -> [Edge];
+	}
+	protocol Edge {
+		associatedtype Node;
+		func Nodes() -> [Node];
+	}
+
+	func ShortestPath<N: Node, E: Edge>(src: N, dst: N) -> [E]
+			where N.Edge == E, E.Node == N {
+		...
+	}
+
+Swift’s default implementation of generic code is by single compilation with run-time substitution, via "[witness tables](https://www.reddit.com/r/swift/comments/3r4gpt/how_is_swift_generics_implemented/cwlo64w/?st=jkwrobje&sh=6741ba8b)".
+The compiler is allowed to compile specialized versions of generic code as an optimization, just as we would like to do for Go.
+
+## Earlier Go Designs
+
+As noted above, the Go team, and in particular Ian Lance Taylor, has been investigating and discussing possible designs for "generics" since before the open source release.
+In April 2016, we
+[published the four main designs](https://go.googlesource.com/proposal/+/master/design/15292-generics.md) we most seriously considered (before the current one).
+Looking back over the designs and comparing them to the current draft design, it is helpful to focus on four features that varied in the designs over time: syntax, type constraints, type inference, and implementation strategy.
+
+**Syntax**.
+How are generic types, funcs, or methods declared? How are generic types, funcs, or methods used?
+
+**Type Constraints**.
+How are type constraints defined?
+
+**Type Inference**.
+When can explicit function call type instantiations be omitted (inferred by the compiler)?
+
+**Implementation**.
+Is compile-time substitution required? Is run-time substitution required? Are both required? Can the compiler choose one or the other as it sees fit?
+
+### [Type Functions](https://go.googlesource.com/proposal/+/master/design/15292/2010-06-type-functions.md), June 2010
+
+The first design we explored was based on the idea of a "type function."
+
+**Syntax.** "Type function" was the name for the syntax for a parameterized type.
+
+	type Vector(T) []T
+
+Every use of a type function had to specify concrete instantiations for the type variables, as in
+
+	type VectorInt Vector(int)
+
+Func definitions introduced type parameters implicitly by use of a type function or explicitly by use of an argument of type "`<name> type`", as in:
+
+	func Sum(x Vector(T type)) T
+
+	func Sum(x []T type) T
+
+**Constraints.**
+Type constraints were specified by optional interface names following the type parameter:
+
+	type PrintableVector(T fmt.Stringer) []T
+
+	func Print(x T type fmt.Stringer)
+
+To allow use of operators like addition in generic code, this proposal relied upon a separate proposal to introduce "operator methods" (as in CLU), which would in turn make them available in interface definitions.
+
+**Inference.** There were no function call type instantiations.
+Instead there was an algorithm for determining the type instantiations, with no explicit fallback when the algorithm failed.
+
+**Implementation.** Overall the goal was to enable writing complex type-independent code once, at a run-time cost: the implementation would always compile only a generic version of the code, which would be passed a type descriptor to supply necessary details.
+This would make generics unsuitable for high-performance uses or even trivial uses like `Min` and `Max`.
+
+If type `Vector(T)` defined a method `Read(b []T) (int, error)`, it was unclear how the generic `Read` implementation specialized to byte would necessarily be compatible in calling convention with `io.Reader`.
+
+The proposal permitted the idea of unbound type parameters
+that seemed to depend on unspecified runtime support, producing "generic values".
+The doc uses as an example:
+
+	func Unknown() T type
+
+	x := Unknown()
+
+It was not clear exactly what this meant or how it would be implemented.
+Overall it seemed that the need for the concept of a "generic value" was an indicator that something was not quite right.
+
+### [Generalized Types](https://go.googlesource.com/proposal/+/master/design/15292/2011-03-gen.md), March 2011
+
+The next design we explored was called "generalized types," although type parameters applied equally to types and functions.
+
+**Syntax.** A type variable was introduced by the syntax `gen [T]` before a declaration and instantiated by listing the types in square brackets after the declared name.
+
+	gen[T] type Vector []T
+
+	type VectorInt Vector[int]
+
+	gen[T] func Sum(x []T) T
+
+	gen[T] func Sum(x Vector[T]) T
+
+	sum := Sum[int]([]int{1,2,3})
+
+    gen[T1, T2] MakePair(x T1, y T2) Pair[T1, T2]
+
+As an aside, we discussed but ultimately rejected reserving `gen` or `generic` as keywords for Go 1 in anticipation of adopting some proposal like this.
+It is interesting to note that the current design avoids the need for any such keyword and does not seem to suffer for it.
+
+**Constraints.** The type variable could be followed by an interface name:
+
+	gen [T Stringer] type PrintableVector []T
+
+	gen [T Stringer] func Print(x T)
+
+The proposal suggested adding language-defined method names for operators, so that `Sum` could be written:
+
+    gen [T] type Number interface {
+    	Plus(T) T
+    }
+
+    gen [T Number[T]] func Sum(x []T) T {
+    	var total T
+    	for _, v := range x {
+    		total = total.Plus(v)
+    	}
+    	return total
+    }
+
+**Inference.** This proposal defined a simple left-to-right greedy unification of the types of the function call arguments with the types of the generic parameter list.
+The current proposal is non-greedy: it unifies the types, and then verifies that all type parameters were unified to the same type.
+The reason the earlier proposal used a greedy algorithm was to handle untyped constants; in the current proposal untyped constants are handled by ignoring them in the first pass and doing a second pass if required.
+
+**Implementation.** This proposal noted that every actual value in a running Go program would have a concrete type.
+It eliminated the "generic values" of the previous proposal.
+
+This was the first proposal that aimed to support both generic and specialized compilation, with an appropriate choice made by the compiler.
+(Because the proposal was never implemented, it is unclear whether it would have achieved that goal.)
+
+### [Generalized Types II](https://go.googlesource.com/proposal/+/master/design/15292/2013-10-gen.md), October 2013
+
+This design was an adaptation of the previous design, at that point two years old, with only one significant change.
+Instead of getting bogged down in specifying interfaces, especially interfaces for operators, the design discarded type constraints entirely.
+This allowed writing `Sum` with the usual `+` operator instead of a new `.Plus` method:
+
+	gen[T] func Sum(x []T) T {
+		s := T(0)
+		for _, v := range x {
+			s += v
+		}
+		return s
+	}
+
+As such, it was the first generics design that did not call for operator methods as well.
+
+Unfortunately, the design did not explain exactly how constraints could be inferred and whether that was even feasible.
+Worse, if contracts are not written down, there’s no way to ensure that an API does not change its requirements accidentally and therefore break clients unexpectedly.
+
+### [Type Parameters](https://go.googlesource.com/proposal/+/master/design/15292/2013-12-type-params.md), December 2013
+
+This design kept most of the semantics of the previous design but introduced new syntax.
+It dropped the gen keyword and moved the type-variable-introducing brackets after the func or type keyword, as in:
+
+	type [T] Vector []T
+
+	type VectorInt Vector[int]
+
+	func [T] Sum(x []T) T
+
+	func [T] Sum(x Vector[T]) T
+
+	sum := Sum[int]([]int{1,2,3})
+
+	func [T1, T2] MakePair(x T1, y T2) Pair[T1, T2]
+
+This design retained the implicit constraints of the previous one, but now with a much longer discussion of exactly how to infer restrictions from function bodies.
+It was still unclear if the approach was workable in practice, and it seemed clearly incomplete.
+The design noted ominously:
+
+> The goal of the restrictions listed above is not to try to handle every possible case.
+> It is to provide a reasonable and consistent approach to type checking of parameterized functions and preliminary type checking of types used to instantiate those functions.
+>
+> It’s possible that future compilers will become more restrictive; a parameterized function that can not be instantiated by any type argument is invalid even if it is never instantiated, but we do not require that every compiler diagnose it.
+> In other words, it’s possible that even if a package compiles successfully today, it may fail to compile in the future if it defines an invalid parameterized function.
+
+Still, after many years of struggling with explicit enumerations of type constraints, "just look at the function body" seemed quite attractive.
+
diff --git a/design/go2draft.md b/design/go2draft.md
new file mode 100644
index 0000000..5c2f805
--- /dev/null
+++ b/design/go2draft.md
@@ -0,0 +1,45 @@
+# Go 2 Draft Designs
+
+As part of the Go 2 design process, we’ve
+[published these draft designs](https://blog.golang.org/go2draft)
+to start community discussions about three topics:
+generics, error handling, and error value semantics.
+
+These draft designs are not proposals in the sense of the [Go proposal process](https://golang.org/s/proposal).
+They are starting points for discussion,
+with an eventual goal of producing designs good enough to be turned into actual proposals.
+
+Each of the draft designs is accompanied by a “problem overview” (think “cover letter”).
+The problem overview is meant to provide context;
+to set the stage for the actual design docs,
+which of course present the design details;
+and to help frame and guide discussion about the designs.
+It presents background, goals, non-goals, design constraints,
+a brief summary of the design,
+a short discussion of what areas we think most need attention,
+and comparison with previous approaches.
+
+Again, these are draft designs, not official proposals. There are not associated proposal issues.
+We hope all Go users will help us improve them and turn them into Go proposals.
+We have established a wiki page to collect and organize feedback about each topic.
+Please help us keep those pages up to date, including by adding links to your own feedback.
+
+**Error handling**:
+
+ - [overview](go2draft-error-handling-overview.md)
+ - [draft design](go2draft-error-handling.md)
+ - [wiki feedback page](https://golang.org/wiki/Go2ErrorHandlingFeedback)
+
+**Error values**:
+
+ - [overview](go2draft-error-values-overview.md)
+ - [draft design for error inspection](go2draft-error-inspection.md)
+ - [draft design for error printing](go2draft-error-printing.md)
+ - [wiki feedback page](https://golang.org/wiki/Go2ErrorValuesFeedback)
+
+**Generics**:
+
+ - [overview](go2draft-generics-overview.md)
+ - [draft design](go2draft-contracts.md)
+ - [wiki feedback page](https://golang.org/wiki/Go2GenericsFeedback)
+