Derive the default transformer name from the function pointer (#113)

If the name is unspecified, try to derive the name from the function pointer.
Deriving the name from the function pointer is not always reliable
since it relies on runtime properties that are not specified to be stable.
diff --git a/cmp/cmpopts/sort.go b/cmp/cmpopts/sort.go
index ddd557b..8b2ef83 100644
--- a/cmp/cmpopts/sort.go
+++ b/cmp/cmpopts/sort.go
@@ -32,7 +32,7 @@
 		panic(fmt.Sprintf("invalid less function: %T", less))
 	}
 	ss := sliceSorter{vf.Type().In(0), vf}
-	return cmp.FilterValues(ss.filter, cmp.Transformer("Sort", ss.sort))
+	return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort))
 }
 
 type sliceSorter struct {
@@ -103,7 +103,7 @@
 		panic(fmt.Sprintf("invalid less function: %T", less))
 	}
 	ms := mapSorter{vf.Type().In(0), vf}
-	return cmp.FilterValues(ms.filter, cmp.Transformer("Sort", ms.sort))
+	return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort))
 }
 
 type mapSorter struct {
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index a776284..c98b088 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -143,7 +143,7 @@
 		label:     label,
 		x:         1,
 		y:         1,
-		opts:      []cmp.Option{cmp.Transformer("", func(x interface{}) interface{} { return x })},
+		opts:      []cmp.Option{cmp.Transformer("λ", func(x interface{}) interface{} { return x })},
 		wantPanic: "cannot use an unfiltered option",
 	}, {
 		label: label,
@@ -151,7 +151,7 @@
 		y:     1,
 		opts: []cmp.Option{
 			cmp.Comparer(func(x, y int) bool { return true }),
-			cmp.Transformer("", func(x int) float64 { return float64(x) }),
+			cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
 		},
 		wantPanic: "ambiguous set of applicable options",
 	}, {
@@ -163,7 +163,7 @@
 				return len(p) > 0 && p[len(p)-1].Type().Kind() == reflect.Int
 			}, cmp.Options{cmp.Ignore(), cmp.Ignore(), cmp.Ignore()}),
 			cmp.Comparer(func(x, y int) bool { return true }),
-			cmp.Transformer("", func(x int) float64 { return float64(x) }),
+			cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
 		},
 	}, {
 		label:     label,
@@ -393,7 +393,7 @@
 		x:     make([]string, 1000),
 		y:     make([]string, 1000),
 		opts: []cmp.Option{
-			cmp.Transformer("", func(x string) int {
+			cmp.Transformer("λ", func(x string) int {
 				return rand.Int()
 			}),
 		},
@@ -405,7 +405,7 @@
 		x:     make([]int, 10),
 		y:     make([]int, 10),
 		opts: []cmp.Option{
-			cmp.Transformer("", func(x int) float64 {
+			cmp.Transformer("λ", func(x int) float64 {
 				return math.NaN()
 			}),
 		},
@@ -441,7 +441,7 @@
 		x:     struct{ I Iface2 }{},
 		y:     struct{ I Iface2 }{},
 		opts: []cmp.Option{
-			cmp.Transformer("", func(v Iface1) bool {
+			cmp.Transformer("λ", func(v Iface1) bool {
 				return v == nil
 			}),
 		},
@@ -497,9 +497,9 @@
 		x:     uint8(0),
 		y:     uint8(1),
 		opts: []cmp.Option{
-			cmp.Transformer("", func(in uint8) uint16 { return uint16(in) }),
-			cmp.Transformer("", func(in uint16) uint32 { return uint32(in) }),
-			cmp.Transformer("", func(in uint32) uint64 { return uint64(in) }),
+			cmp.Transformer("λ", func(in uint8) uint16 { return uint16(in) }),
+			cmp.Transformer("λ", func(in uint16) uint32 { return uint32(in) }),
+			cmp.Transformer("λ", func(in uint32) uint64 { return uint64(in) }),
 		},
 		wantDiff: `
 λ(λ(λ({uint8}))):
@@ -510,8 +510,8 @@
 		x:     0,
 		y:     1,
 		opts: []cmp.Option{
-			cmp.Transformer("", func(in int) int { return in / 2 }),
-			cmp.Transformer("", func(in int) int { return in }),
+			cmp.Transformer("λ", func(in int) int { return in / 2 }),
+			cmp.Transformer("λ", func(in int) int { return in }),
 		},
 		wantPanic: "ambiguous set of applicable options",
 	}, {
@@ -521,11 +521,11 @@
 		opts: []cmp.Option{
 			cmp.FilterValues(
 				func(x, y int) bool { return x+y >= 0 },
-				cmp.Transformer("", func(in int) int64 { return int64(in / 2) }),
+				cmp.Transformer("λ", func(in int) int64 { return int64(in / 2) }),
 			),
 			cmp.FilterValues(
 				func(x, y int) bool { return x+y < 0 },
-				cmp.Transformer("", func(in int) int64 { return int64(in) }),
+				cmp.Transformer("λ", func(in int) int64 { return int64(in) }),
 			),
 		},
 		wantDiff: `
@@ -540,7 +540,7 @@
 		x:     0,
 		y:     1,
 		opts: []cmp.Option{
-			cmp.Transformer("", func(in int) interface{} {
+			cmp.Transformer("λ", func(in int) interface{} {
 				if in == 0 {
 					return "string"
 				}
@@ -1816,7 +1816,7 @@
 
 	ignoreLocker := cmpopts.IgnoreInterfaces(struct{ sync.Locker }{})
 
-	transformProtos := cmp.Transformer("", func(x pb.Dirt) *pb.Dirt {
+	transformProtos := cmp.Transformer("λ", func(x pb.Dirt) *pb.Dirt {
 		return &x
 	})
 
@@ -1903,7 +1903,7 @@
 		ts.Poison{},
 	)
 
-	transformProtos := cmp.Transformer("", func(x pb.Restrictions) *pb.Restrictions {
+	transformProtos := cmp.Transformer("λ", func(x pb.Restrictions) *pb.Restrictions {
 		return &x
 	})
 
diff --git a/cmp/options.go b/cmp/options.go
index ccd78c4..a9306b4 100644
--- a/cmp/options.go
+++ b/cmp/options.go
@@ -237,9 +237,11 @@
 		panic(fmt.Sprintf("invalid transformer function: %T", f))
 	}
 	if name == "" {
-		name = "λ" // Lambda-symbol as place-holder for anonymous transformer
-	}
-	if !identsRx.MatchString(name) {
+		name = function.NameOf(v)
+		if !identsRx.MatchString(name) {
+			name = "λ" // Lambda-symbol as placeholder name
+		}
+	} else if !identsRx.MatchString(name) {
 		panic(fmt.Sprintf("invalid name: %q", name))
 	}
 	tr := &transformer{name: name, fnc: reflect.ValueOf(f)}