tour: add a basic explanation and examples of generics to the Tour of Go

Change-Id: Iad4a0bf762b023b14d3f9c532da31674fcca804c
Reviewed-on: https://go-review.googlesource.com/c/website/+/370174
Reviewed-by: DO NOT USE <iant@google.com>
Trust: Cherry Mui <cherryyz@google.com>
diff --git a/_content/tour/generics.article b/_content/tour/generics.article
new file mode 100644
index 0000000..4d6f97e
--- /dev/null
+++ b/_content/tour/generics.article
@@ -0,0 +1,42 @@
+Generics
+Go supports generic programming using type parameters. This lesson shows some examples for employing generics in your code.
+
+The Go Authors
+https://golang.org
+
+* Type parameters
+
+Go functions can be written to work on multiple types using type parameters. The
+type parameters of a function appear between brackets, before the function's
+arguments.
+
+  func Index[T comparable](s []T, x T) int
+
+This declaration means that `s` is a slice of any type `T` that fulfills the
+built-in constraint `comparable`. `x` is also a value of the same type.
+
+`comparable` is a useful constraint that makes it possible to use the `==` and
+`!=` operators on values of the type. In this example, we use it to compare a
+value to all slice elements until a match is found. This `Index` function works
+for any type that supports comparison.
+
+.play generics/index.go
+
+* Generic types
+
+In addition to generic functions, Go also supports generic types. A type can
+be parameterized with a type paremeter, which could be useful for implementing
+generic data structures.
+
+This example demonstrates a simple type declaration for a singly-linked list
+holding any type of value.
+
+As an exercise, add some functionality to this list implementation.
+
+.play generics/list.go
+
+* Congratulations!
+
+You finished this lesson!
+
+You can go back to the list of [[/tour/list][modules]] to find what to learn next, or continue with the [[javascript:click('.next-page')][next lesson]].
diff --git a/_content/tour/generics/index.go b/_content/tour/generics/index.go
new file mode 100644
index 0000000..b29eae2
--- /dev/null
+++ b/_content/tour/generics/index.go
@@ -0,0 +1,28 @@
+//go:build OMIT
+// +build OMIT
+
+package main
+
+import "fmt"
+
+// Index returns the index of x in s, or -1 if not found.
+func Index[T comparable](s []T, x T) int {
+	for i, v := range s {
+		// v and x are type T, which has the comparable
+		// constraint, so we can use == here.
+		if v == x {
+			return i
+		}
+	}
+	return -1
+}
+
+func main() {
+	// Index works on a slice of ints
+	si := []int{10, 20, 15, -10}
+	fmt.Println(Index(si, 15))
+
+	// Index also works on a slice of strings
+	ss := []string{"foo", "bar", "baz"}
+	fmt.Println(Index(ss, "hello"))
+}
diff --git a/_content/tour/generics/list.go b/_content/tour/generics/list.go
new file mode 100644
index 0000000..a3fb309
--- /dev/null
+++ b/_content/tour/generics/list.go
@@ -0,0 +1,11 @@
+package main
+
+// List represents a singly-linked list that holds
+// values of any type.
+type List[T any] struct {
+	next *List[T]
+	val  T
+}
+
+func main() {
+}
diff --git a/_content/tour/static/js/values.js b/_content/tour/static/js/values.js
index 068c8c2..9dff116 100644
--- a/_content/tour/static/js/values.js
+++ b/_content/tour/static/js/values.js
@@ -23,6 +23,11 @@
     'description': '<p>Learn how to define methods on types, how to declare interfaces, and how to put everything together.</p>',
     'lessons': ['methods']
 }, {
+    'id': 'generics',
+    'title': 'Generics',
+    'description': '<p>Learn how to use type parameters in Go functions and structs.</p>',
+    'lessons': ['generics']
+}, {
     'id': 'concurrency',
     'title': 'Concurrency',
     'description': '<p>Go provides concurrency features as part of the core language.</p><p>This module goes over goroutines and channels, and how they are used to implement different concurrency patterns.</p>',