From: Robert Griesemer  
 A struct is a sequence of named
 elements, called fields, with various types. A struct type declares
-an identifier and type for each field. Within a struct, field identifiers
-must be unique.
+an identifier and type for each field. Within a struct, non-blank
+field identifiers must be unique.
  
-Blocks nest and influence scoping (§Declarations and scope).
+Blocks nest and influence scoping.
  
-A declaration binds an identifier to a constant, type, variable, function, or package.
+A declaration binds a non-blank
+identifier to a constant, type, variable, function, or package.
 Every identifier in a program must be declared.
 No identifier may be declared twice in the same block, and
 no identifier may be declared in both the file and package block.
@@ -1372,6 +1377,14 @@ All other identifiers are not exported.
  
+The blank identifier, represented by the underscore character  
@@ -1449,7 +1462,7 @@ set of related constants:
  
@@ -1589,12 +1605,13 @@ i, j := 0, 10;
 f := func() int { return 7; }
 ch := make(chan int);
 r, w := os.Pipe(fd);  // os.Pipe() returns two values
+_, y, _ := coord(p);  // coord() returns three values; only interested in y "projection"
 
 
  
 Unlike regular variable declarations, a short variable declaration may redeclare variables provided they
 were originally declared in the same block with the same type, and at
-least one of the variables is new.  As a consequence, redeclaration
+least one of the non-blank variables is new.  As a consequence, redeclaration
 can only appear in a multi-variable short declaration.
 Redeclaration does not introduce a new
 variable; it just assigns a new value to the original.
@@ -1734,12 +1751,11 @@ Constants have values that are known at compile time.
  
-A qualified identifier is an identifier qualified by a package name prefix.
+A qualified identifier is a non-blank identifier qualified by a package name prefix.
  
@@ -1752,6 +1768,10 @@ package, which means that it must begin with a Unicode upper case letter.
 Math.Sin
 
 
+ 
+TODO: Unify this section with Selectors - it's the same syntax.
+ 
@@ -1998,7 +2018,7 @@ denotes the field or method  
@@ -3096,7 +3116,7 @@ assign_op = [ add_op | mul_op ] "=" .
 
  
 Each left-hand side operand must be a variable, pointer indirection,
-field selector, or index expression.
+field selector, index expression, or blank identifier.
 Keywords
 
@@ -665,8 +665,8 @@ new([100]int)[0:50]
 
@@ -680,10 +680,11 @@ Tag = StringLit .
 // An empty struct.
 struct {}
 
-// A struct with 5 fields.
+// A struct with 6 fields.
 struct {
 	x, y int;
 	u float;
+	_ float;  // padding
 	A *[]int;
 	F func();
 }
@@ -1168,6 +1169,9 @@ A bidirectional channel c can be assigned to a channel variable
 v with compatible channel value type
 if the type of c or v is unnamed.
 
+Comparison compatibility
@@ -1244,7 +1248,7 @@ In addition to explicit blocks in the source code, there are implicit blocks:
 
 	
Declarations and scope
 
 Blank identifier
+
+_, may be used in a declaration like
+any other identifier but the declaration does not introduce a new binding.
+Const declarations
 
 
-const (            // iota is reset to 0
+const (  // iota is reset to 0
 	c0 = iota;  // c0 == 0
 	c1 = iota;  // c1 == 1
 	c2 = iota   // c2 == 2
@@ -1480,7 +1493,8 @@ it is only incremented at a semicolon:
 const (
 	bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
 	bit1, mask1;                             // bit1 == 2, mask1 == 1
-	bit2, mask2;                             // bit2 == 4, mask2 == 3
+	_, _;                                    // skips iota == 2
+	bit3, mask3;                             // bit3 == 8, mask3 == 7
 )
 
 
@@ -1542,6 +1556,8 @@ var (
 	i int;
 	u, v, s = 2.0, 3.0, "bar"
 )
+var re, im = complexSqrt(-1)
+var _, found = entries[name];  // map lookup; only interested in "found"
 
 
 Qualified identifiers
 
 
 QualifiedIdent = [ PackageName "." ] identifier .
-PackageName = identifier .
 
 
 Composite literals
 
 f of the value denoted by x*x if
 x is of pointer type). The identifier f
 is called the (field or method)
-selector.
+selector; it must not be the blank identifier.
 The type of the expression is the type of f.
 
@@ -3126,7 +3146,7 @@ first, the right hand operand is a single multi-valued expression
 such as a function evaluation or channel or
 map operation or a type assertion.
 The number of operands on the left
-hand side must match the number of values.  For instance, If
+hand side must match the number of values.  For instance, if
 
f is a function returning two values,
 
 assigns the first value to x and the second to y.
+The blank identifier provides a convenient
+way to ignore values returned by a multi-valued expression:
 
+x, _ = f() // ignore second value returned by f() ++
In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the @@ -3998,7 +4024,7 @@ m := make(map[string] int, 100); # map with initial space for 100 elements Go programs are constructed by linking together packages. A package is in turn constructed from one or more source files that together provide access to a set of types, constants, functions, -and variables. Those elements may be imported and used in +and variables. Those elements may be exported and used in another package.
@@ -4024,9 +4050,14 @@ to which the file belongs.-PackageClause = "package" PackageName . +PackageClause = "package" PackageName . +PackageName = identifier .+
+The PackageName must not be the blank identifier. +
+package math