content: rewrite slices section

This rewrite introduces slices in terms of arrays,
before introducing make. I think it flows more nicely.

Fixes golang/go#13883
Fixes golang/go#14893

Change-Id: Idd0c6de29c0207d755cac673e580efee6c34a7b2
Reviewed-on: https://go-review.googlesource.com/21358
Reviewed-by: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/content/moretypes.article b/content/moretypes.article
index a410fb5..bfae74f 100644
--- a/content/moretypes.article
+++ b/content/moretypes.article
@@ -64,6 +64,7 @@
 
 .play moretypes/struct-literals.go
 
+
 * Arrays
 
 The type `[n]T` is an array of `n` values of type `T`.
@@ -80,45 +81,110 @@
 
 .play moretypes/array.go
 
+
 * Slices
 
-A slice points to an array of values and also includes a length.
+An array has a fixed size.
+A slice, on the other hand, is a dynamically-sized,
+flexible view into the elements of an array.
+In practice, slices are much more common than arrays.
 
-`[]T` is a slice with elements of type `T`.
+The type `[]T` is a slice with elements of type `T`.
 
-`len(primes)` returns the length of slice `primes`.
+This expression creates a slice of the first five elements of the array `a`:
+
+	a[0:5]
+
 
 .play moretypes/slices.go
 
-* Slices of Slices
 
-Slices can contain any type, including other slices.
+* Slices are like references to arrays
 
-.play moretypes/slices-of-slice.go
+A slice does not store any data,
+it just describes a section of an underlying array.
 
-* Slicing slices
+Changing the elements of a slice modifies the
+corresponding elements of its underlying array.
 
-Slices can be re-sliced, creating a new slice value that points to the same array.
+Other slices that share the same underlying array will see those changes.
 
-The expression
+.play moretypes/slices-pointers.go
 
-	s[lo:hi]
 
-evaluates to a slice of the elements from `lo` through `hi-1`, inclusive. Thus
+* Slice literals
 
-	s[lo:lo]
+A slice literal is like an array literal without the length.
 
-is empty and
+This is an array literal:
 
-	s[lo:lo+1]
+	[3]bool{true, true, false}
 
-has one element.
+And this creates the same array as above,
+then builds a slice that references it:
 
-.play moretypes/slicing-slices.go
+	[]bool{true, true, false}
 
-* Making slices
+.play moretypes/slice-literals.go
 
-Slices are created with the `make` function. It works by allocating a zeroed array and returning a slice that refers to that array:
+
+* Slice defaults
+
+When slicing, you may omit the high or low bounds to use their defaults instead.
+
+The default is zero for the low bound and the length of the slice for the high bound.
+
+For the array
+
+	var a [10]int
+
+these slice expressions are equivalent:
+
+	a[0:10]
+	a[:10]
+	a[0:]
+	a[:]
+
+.play moretypes/slice-bounds.go
+
+
+* Slice length and capacity
+
+A slice has both a _length_ and a _capacity_.
+
+The length of a slice is the number of elements it contains.
+
+The capacity of a slice is the number of elements in the underlying array,
+counting from the first element in the slice.
+
+The length and capacity of a slice `s` can be obtained using the expressions
+`len(s)` and `cap(s)`.
+
+You can extend a slice's length by re-slicing it,
+provided it has sufficient capacity.
+Try changing one of the slice operations in the example program to extend it
+beyond its capacity and see what happens.
+
+.play moretypes/slice-len-cap.go
+
+
+* Nil slices
+
+The zero value of a slice is `nil`.
+
+A nil slice has a length and capacity of 0
+and has no underlying array.
+
+.play moretypes/nil-slices.go
+
+
+* Creating a slice with make
+
+Slices can be created with the built-in `make` function;
+this is how you create dynamically-sized arrays.
+
+The `make` function allocates a zeroed array
+and returns a slice that refers to that array:
 
 	a := make([]int, 5)  // len(a)=5
 
@@ -131,15 +197,15 @@
 
 .play moretypes/making-slices.go
 
-* Nil slices
 
-The zero value of a slice is `nil`.
+* Slices of slices
 
-A nil slice has a length and capacity of 0.
+Slices can contain any type, including other slices.
 
-.play moretypes/nil-slices.go
+.play moretypes/slices-of-slice.go
 
-* Adding elements to a slice
+
+* Appending to a slice
 
 It is common to append new elements to a slice, and so Go provides a built-in
 `append` function. The [[https://golang.org/pkg/builtin/#append][documentation]]
@@ -161,6 +227,7 @@
 
 .play moretypes/append.go
 
+
 * Range
 
 The `range` form of the `for` loop iterates over a slice or map.
diff --git a/content/moretypes/array.go b/content/moretypes/array.go
index 8626743..8d73573 100644
--- a/content/moretypes/array.go
+++ b/content/moretypes/array.go
@@ -10,4 +10,7 @@
 	a[1] = "World"
 	fmt.Println(a[0], a[1])
 	fmt.Println(a)
+
+	primes := [6]int{2, 3, 5, 7, 11, 13}
+	fmt.Println(primes)
 }
diff --git a/content/moretypes/slice-bounds.go b/content/moretypes/slice-bounds.go
new file mode 100644
index 0000000..1ba3963
--- /dev/null
+++ b/content/moretypes/slice-bounds.go
@@ -0,0 +1,18 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+	s := []int{2, 3, 5, 7, 11, 13}
+
+	s = s[1:4]
+	fmt.Println(s)
+
+	s = s[:2]
+	fmt.Println(s)
+
+	s = s[1:]
+	fmt.Println(s)
+}
diff --git a/content/moretypes/slice-len-cap.go b/content/moretypes/slice-len-cap.go
new file mode 100644
index 0000000..a1c5764
--- /dev/null
+++ b/content/moretypes/slice-len-cap.go
@@ -0,0 +1,26 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+	s := []int{2, 3, 5, 7, 11, 13}
+	printSlice(s)
+
+	// Slice the slice to give it zero length.
+	s = s[:0]
+	printSlice(s)
+
+	// Extend its length.
+	s = s[:4]
+	printSlice(s)
+
+	// Drop its first two values.
+	s = s[2:]
+	printSlice(s)
+}
+
+func printSlice(s []int) {
+	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
+}
diff --git a/content/moretypes/slice-literals.go b/content/moretypes/slice-literals.go
new file mode 100644
index 0000000..5a98010
--- /dev/null
+++ b/content/moretypes/slice-literals.go
@@ -0,0 +1,26 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+	q := []int{2, 3, 5, 7, 11, 13}
+	fmt.Println(q)
+
+	r := []bool{true, false, true, true, false, true}
+	fmt.Println(r)
+
+	s := []struct {
+		i int
+		b bool
+	}{
+		{2, true},
+		{3, false},
+		{5, true},
+		{7, true},
+		{11, false},
+		{13, true},
+	}
+	fmt.Println(s)
+}
diff --git a/content/moretypes/slices-pointers.go b/content/moretypes/slices-pointers.go
new file mode 100644
index 0000000..193b463
--- /dev/null
+++ b/content/moretypes/slices-pointers.go
@@ -0,0 +1,23 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+	names := [4]string{
+		"John",
+		"Paul",
+		"George",
+		"Ringo",
+	}
+	fmt.Println(names)
+
+	a := names[0:2]
+	b := names[1:3]
+	fmt.Println(a, b)
+
+	b[0] = "XXX"
+	fmt.Println(a, b)
+	fmt.Println(names)
+}
diff --git a/content/moretypes/slices.go b/content/moretypes/slices.go
index 385283c..7720f84 100644
--- a/content/moretypes/slices.go
+++ b/content/moretypes/slices.go
@@ -5,10 +5,8 @@
 import "fmt"
 
 func main() {
-	primes := []int{2, 3, 5, 7, 11, 13}
-	fmt.Println("primes ==", primes)
+	primes := [6]int{2, 3, 5, 7, 11, 13}
 
-	for i := 0; i < len(primes); i++ {
-		fmt.Printf("primes[%d] == %d\n", i, primes[i])
-	}
+	var s []int = primes[1:4]
+	fmt.Println(s)
 }
diff --git a/content/moretypes/slicing-slices.go b/content/moretypes/slicing-slices.go
deleted file mode 100644
index 27e1aef..0000000
--- a/content/moretypes/slicing-slices.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// +build OMIT
-
-package main
-
-import "fmt"
-
-func main() {
-	s := []int{2, 3, 5, 7, 11, 13}
-	fmt.Println("s ==", s)
-	fmt.Println("s[1:4] ==", s[1:4])
-
-	// missing low index implies 0
-	fmt.Println("s[:3] ==", s[:3])
-
-	// missing high index implies len(s)
-	fmt.Println("s[4:] ==", s[4:])
-}