]> Cypherpunks repositories - gostls13.git/commitdiff
Move Types before Declarations and Scopes.
authorRob Pike <r@golang.org>
Tue, 24 Feb 2009 03:26:07 +0000 (19:26 -0800)
committerRob Pike <r@golang.org>
Tue, 24 Feb 2009 03:26:07 +0000 (19:26 -0800)
This is the only change in this CL: only rearrangement, no content change, so subsequent edits will be easier to understand.

R=gri
OCL=25353
CL=25353

doc/go_spec.html

index f3a52b970a540a3e4b27759e80b82a10d46e5811..32ac34e3db2bb89de1f7a28ad972313205a578f5 100644 (file)
@@ -538,1269 +538,1270 @@ literal.
 </p>
 <hr/>
 
-<h2>Declarations and Scope</h2>
+<h2>Types</h2>
 
+A type specifies the set of values that variables of that type may assume
+and the operators that are applicable.
 <p>
-A declaration binds an identifier to a language entity such as
-a variable or function and specifies properties such as its type.
-Every identifier in a program must be declared.
-</p>
+A type may be specified by a type name (§Type declarations) or a type literal.
+A type literal is a syntactic construct that explicitly specifies the
+composition of a new type in terms of other (already declared) types.
 
 <pre class="grammar">
-Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
+Type = TypeName | TypeLit | "(" Type ")" .
+TypeName = QualifiedIdent.
+TypeLit =
+       ArrayType | StructType | PointerType | FunctionType | InterfaceType |
+       SliceType | MapType | ChannelType .
 </pre>
-               
+
+Some types are predeclared and denoted by their type names; these are called
+``basic types''. Generally (except for strings) they are not composed of more
+elementary types; instead they model elementary machine data types.
 <p>
-The <i>scope</i> of an identifier is the extent of source text within which the
-identifier denotes the bound entity. No identifier may be declared twice in a
-single scope, but inner blocks can declare a new entity with the same
-identifier, in which case the scope created by the outer declaration excludes
-that created by the inner.
-</p>
+All other types are called ``composite types'; they are composed from other
+(basic or composite) types and denoted by their type names or by type literals.
+There are arrays, structs, pointers, functions, interfaces, slices, maps, and
+channels.
 <p>
-There are levels of scoping in effect before each source file is compiled.
-In order from outermost to innermost:
-</p>
-<ol>
-       <li>The <i>universe</i> scope contains all predeclared identifiers.</li>
-       <li>An implicit scope contains only the package name.</li>
-       <li>The <i>package-level</i> scope surrounds all declarations at the
-           top level of the file, that is, outside the body of any
-           function or method.  That scope is shared across all
-           source files within the package (§Packages), allowing
-           package-level identifiers to be shared between source
-           files.</li>
-</ol>
+At a given point in the source code, a type may be ``complete'' or
+''incomplete''. Array and struct types are complete when they are fully declared.
+All other types are always complete (although their components, such as the base
+type of a pointer type, may be incomplete). Incomplete types are subject to usage
+restrictions; for instance the type of a variable must be complete where the
+variable is declared.
 
+The ``interface'' of a type is the set of methods bound to it
+(§Method declarations). The interface of a pointer type is the interface
+of the pointer base type (§Pointer types). All types have an interface;
+if they have no methods associated with them, their interface is
+called the ``empty'' interface.
 <p>
-The scope of an identifier depends on the entity declared:
-</p>
-
-<ol>
-       <li> The scope of predeclared identifiers is the universe scope.</li>
-
-       <li> The scope of an (identifier denoting a) type, function or package
-            extends from the point of the identifier in the declaration
-            to the end of the innermost surrounding block.</li>
+The ``static type'' (or simply ``type'') of a variable is the type defined by
+the variable's declaration. The ``dynamic type'' of a variable is the actual
+type of the value stored in a variable at run-time. Except for variables of
+interface type, the dynamic type of a variable is always its static type.
+<p>
+Variables of interface type may hold values with different dynamic types
+during execution. However, its dynamic type is always compatible with
+the static type of the interface variable (§Interface types).
+       
 
-       <li> The scope of a constant or variable extends textually from
-            the end of the declaration to the end of the innermost
-            surrounding block. If the variable is declared in the
-            <i>init</i> statement of an <code>if </code>,  <code>for</code>,
-            or  <code>switch </code> statement, the
-            innermost surrounding block is the block associated
-            with that statement.</li>
+<h3>Basic types</h3>
 
-       <li> The scope of a parameter or result is the body of the
-            corresponding function.</li>
+Go defines a number of basic types, referred to by their predeclared
+type names.  These include traditional arithmetic types, booleans,
+and strings.
 
-       <li> The scope of a field or method is selectors for the
-            corresponding type containing the field or method (§Selectors).</li>
 
-       <li> The scope of a label is a unique scope emcompassing
-            the body of the innermost surrounding function, excluding
-            nested functions.  Labels do not conflict with variables.</li>
-</ol>
+<h3>Arithmetic types</h3>
 
-<h3>Predeclared identifiers</h3>
+The following list enumerates all platform-independent numeric types:
 
-<p>
-The following identifiers are implicitly declared in the outermost scope:
-</p>
 <pre class="grammar">
-Basic types:
-       bool byte float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64
-
-Platform-specific convenience types:
-       float int uint uintptr
+byte     same as uint8 (for convenience)
 
-Constants:
-       true false iota nil
+uint8    the set of all unsigned  8-bit integers (0 to 255)
+uint16   the set of all unsigned 16-bit integers (0 to 65535)
+uint32   the set of all unsigned 32-bit integers (0 to 4294967295)
+uint64   the set of all unsigned 64-bit integers (0 to 18446744073709551615)
 
-Functions:
-       cap convert len make new panic panicln print println typeof (TODO: typeof??)
+int8     the set of all signed  8-bit integers (-128 to 127)
+int16    the set of all signed 16-bit integers (-32768 to 32767)
+int32    the set of all signed 32-bit integers (-2147483648 to 2147483647)
+int64    the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
 
-Packages:
-       sys unsafe  (TODO: does sys endure?)
+float32  the set of all valid IEEE-754 32-bit floating point numbers
+float64  the set of all valid IEEE-754 64-bit floating point numbers
 </pre>
 
+Integer types are represented in the usual binary format; the value of
+an n-bit integer is n bits wide. A negative signed integer is represented
+as the two's complement of its absolute value.
 
-<h3>Exported identifiers</h3>
+<!--
+The representation of signed integers and their exact range is
+implementation-specific, but the set of all positive values (including zero)
+of a signed integer type is always a subset of the corresponding unsigned
+integer type (thus, a positive signed integer can always be converted into
+its corresponding unsigned type without loss).
+-->
 
-<p>
-By default, identifiers are visible only within the package in which they are declared.
-Some identifiers are <i>exported</i> and can be referenced using
-<i>qualified identifiers</i> in other packages (§Qualified identifiers).
-If an identifier satisfies these two conditions:
-</p>
-<ol>
-<li>the first character of the identifier's name is a Unicode upper case letter;
-<li>the identifier is declared at the package level or is a field or method of a type
-declared at the top level;
-</ol>
-<p>
-it will be exported automatically.
-</p>
+Additionally, Go declares a set of platform-specific numeric types for
+convenience:
 
-<h3>Const declarations</h3>
+<pre class="grammar">
+uint     at least 32 bits, at most the size of the largest uint type
+int      at least 32 bits, at most the size of the largest int type
+float    at least 32 bits, at most the size of the largest float type
+uintptr  smallest uint type large enough to store the uninterpreted
+                bits of a pointer value
+</pre>
 
+For instance, int might have the same size as int32 on a 32-bit
+architecture, or int64 on a 64-bit architecture.
 <p>
-A constant declaration binds a list of identifiers (the names of
-the constants) to the values of a list of constant expressions
-(§Constant expressions).  The number of identifiers must be equal
-to the number of expressions, and the n<sup>th</sup> identifier on
-the left is bound to value of the n<sup>th</sup> expression on the
-right.
-</p>
+Except for "byte", which is an alias for "uint8", all numeric types
+are different from each other to avoid portability issues. Conversions
+are required when different numeric types are mixed in an expression or assignment.
+For instance, "int32" and "int" are not the same type even though they may have
+the same size on a particular platform.
 
-<pre class="grammar">
-ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
-ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
-ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
 
-IdentifierList = identifier { "," identifier } .
-ExpressionList = Expression { "," Expression } .
+<h3>Booleans</h3>
 
-CompleteType = Type .
-</pre>
+The type "bool" comprises the truth values true and false, which are
+available through the two predeclared constants, "true" and "false".
 
-<p>
-If the type (CompleteType) is omitted, the constants take the
-individual types of the corresponding expressions, which may be
-``ideal integer'' or ``ideal float'' (§Ideal number).  If the type
-is present, all constants take the type specified, and the types
-of all the expressions must be assignment-compatible
-with that type.
-</p>
 
-<pre>
-const Pi float64 = 3.14159265358979323846
-const E = 2.718281828
-const (
-       size int64 = 1024;
-       eof = -1;
-)
-const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo"
-const u, v float = 0, 3      // u = 0.0, v = 3.0
-</pre>
+<h3>Strings</h3>
 
 <p>
-Within a parenthesized <code>const</code> declaration list the
-expression list may be omitted from any but the first declaration.
-Such an empty list is equivalent to the textual substitution of the
-first preceding non-empty expression list.  Omitting the list of
-expressions is therefore equivalent to repeating the previous list.
-The number of identifiers must be equal to the number of expressions
-in the previous list.  Together with the <code>iota</code> constant generator
-(§Iota) this mechanism permits light-weight declaration of sequential values:
+The "string" type represents the set of string values (strings).
+Strings behave like arrays of bytes, with the following properties:
 </p>
+<ul>
+<li>They are immutable: after creation, it is not possible to change the
+contents of a string.
+<li>No internal pointers: it is illegal to create a pointer to an inner
+element of a string.
+<li>They can be indexed: given string "s1", "s1[i]" is a byte value.
+<li>They can be concatenated: given strings "s1" and "s2", "s1 + s2" is a value
+combining the elements of "s1" and "s2" in sequence.
+<li>Known length: the length of a string "s1" can be obtained by calling
+"len(s1)".  The length of a string is the number
+of bytes within. Unlike in C, there is no terminal NUL byte.
+<li>Creation 1: a string can be created from an integer value by a conversion;
+the result is a string containing the UTF-8 encoding of that code point
+(§Conversions).
+"string('x')" yields "x"; "string(0x1234)" yields the equivalent of "\u1234"
 
+<li>Creation 2: a string can by created from an array of integer values (maybe
+just array of bytes) by a conversion (§Conversions):
 <pre>
-const (
-       Sunday = iota;
-       Monday;
-       Tuesday;
-       Wednesday;
-       Thursday;
-       Friday;
-       Partyday;
-       numberOfDays;  // this constant is not exported
-)
+a [3]byte; a[0] = 'a'; a[1] = 'b'; a[2] = 'c';  string(a) == "abc";
 </pre>
+</ul>
 
 
-<h3>Iota</h3>
+<h3>Array types</h3>
 
-<p>
-Within a constant declaration, the predeclared pseudo-constant
-<code>iota</code> represents successive integers. It is reset to 0
-whenever the reserved word <code>const</code> appears in the source
-and increments with each semicolon. It can be used to construct a
-set of related constants:
-</p>
+An array is a composite type consisting of a number of elements all of the
+same type, called the element type. The element type must be a complete type
+(§Types). The number of elements of an array is called its length; it is never
+negative. The elements of an array are designated by indices
+which are integers from 0 through the length - 1.
 
-<pre>
-const (            // iota is reset to 0
-       c0 = iota;  // c0 == 0
-       c1 = iota;  // c1 == 1
-       c2 = iota   // c2 == 2
-)
-
-const (
-       a = 1 << iota;  // a == 1 (iota has been reset)
-       b = 1 << iota;  // b == 2
-       c = 1 << iota;  // c == 4
-)
+<pre class="grammar">
+ArrayType = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = CompleteType .
+</pre>
 
-const (
-       u       = iota * 42;  // u == 0     (ideal integer)
-       v float = iota * 42;  // v == 42.0  (float)
-       w       = iota * 42;  // w == 84    (ideal integer)
-)
+The array length and its value are part of the array type. The array length
+must be a constant expression (§Constant expressions) that evaluates to an
+integer value >= 0.
+<p>
+The number of elements of an array "a" can be discovered using the built-in
+function
 
-const x = iota;  // x == 0 (iota has been reset)
-const y = iota;  // y == 0 (iota has been reset)
+<pre>
+len(a)
 </pre>
 
-<p>
-Within an ExpressionList, the value of each <code>iota</code> is the same because
-it is only incremented at a semicolon:
-</p>
+The length of arrays is known at compile-time, and the result of a call to
+"len(a)" is a compile-time constant.
 
 <pre>
-const (
-       bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
-       bit1, mask1;                             // bit1 == 2, mask1 == 1
-       bit2, mask2;                             // bit2 == 4, mask2 == 3
-)
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
 </pre>
 
-<p>
-This last example exploits the implicit repetition of the
-last non-empty expression list.
-</p>
+Assignment compatibility: Arrays can be assigned to variables of equal type
+and to slice variables with equal element type. When assigning to a slice
+variable, the array is not copied but a slice comprising the entire array
+is created.
 
 
-<h3>Type declarations</h3>
+<h3>Struct types</h3>
 
-<p>
-A type declaration binds an identifier, the <i>type name</i>,
-to a new type.  <font color=red>TODO: what exactly is a "new type"?</font>
-</p>
+A struct is a composite type consisting of a fixed number of elements,
+called fields, with possibly different types. A struct type declares
+an identifier and type for each field. Within a struct type no field
+identifier may be declared twice and all field types must be complete
+types (§Types).
 
 <pre class="grammar">
-TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
-TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
-TypeSpec     = identifier Type .
+StructType = "struct" [ "{" [ FieldDeclList ] "}" ] .
+FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] .
+FieldDecl = (IdentifierList CompleteType | [ "*" ] TypeName) [ Tag ] .
+Tag = StringLit .
 </pre>
 
 <pre>
-type IntArray [16] int
-
-type (
-       Point struct { x, y float };
-       Polar Point
-)
-
-type TreeNode struct {
-       left, right *TreeNode;
-       value Point;
-}
+// An empty struct.
+struct {}
 
-type Comparable interface {
-       cmp(Comparable) int
+// A struct with 5 fields.
+struct {
+       x, y int;
+       u float;
+       A *[]int;
+       F func();
 }
 </pre>
 
-<h3>Variable declarations</h3>
+A struct may contain ``anonymous fields'', which are declared with a type
+but no explicit field identifier. An anonymous field type must be specified as
+a type name "T", or as a pointer to a type name ``*T'', and T itself may not be
+a pointer or interface type. The unqualified type name acts as the field identifier.
 
-<p>
-A variable declaration creates a variable, binds an identifier to it and
-gives it a type and optionally an initial value.
-The variable type must be a complete type (§Types).
-</p>
-<pre class="grammar">
-VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
-VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
-VarSpec     = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
+<pre>
+// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
+struct {
+       T1;        // the field name is T1
+       *T2;       // the field name is T2
+       P.T3;      // the field name is the unqualified type name T3
+       *P.T4;     // the field name is the unqualified type name T4
+       x, y int;  
+}
 </pre>
 
+The unqualified type name of an anonymous field must not conflict with the
+field identifier (or unqualified type name for an anonymous field) of any
+other field within the struct. The following declaration is illegal:
+
 <pre>
-var i int
-var U, V, W float
-var k = 0
-var x, y float = -1.0, -2.0
-var (
-       i int;
-       u, v, s = 2.0, 3.0, "bar"
-)
+struct {
+       T;         // conflicts with anonymous field *T and *P.T
+       *T;        // conflicts with anonymous field T and *P.T
+       *P.T;      // conflicts with anonymous field T and *T
+}
 </pre>
 
+Fields and methods (§Method declarations) of an anonymous field become directly
+accessible as fields and methods of the struct without the need to provide the
+type name of the respective anonymous field (§Selectors).
 <p>
-If there are expressions, their number must be equal
-to the number of identifiers, and the n<sup>th</sup> variable
-is initialized to the value of the n<sup>th</sup> expression.
-Otherwise, each variable is initialized to the <i>zero</i>
-of the type (§Program initialization and execution).
-The expressions can be general expressions; they need not be constants.
-</p>
-<p>
-Either the type or the expression list must be present.  If the
-type is present, it sets the type of each variable and the expressions
-(if any) must be assignment-compatible to that type.  If the type
-is absent, the variables take the types of the corresponding
-expressions.
-</p>
-<p>
-If the type is absent and the corresponding expression is a constant
-expression of ideal integer or ideal float type, the type of the
-declared variable is <code>int</code> or <code>float</code>
-respectively:
-</p>
+A field declaration may be followed by an optional string literal tag which
+becomes an ``attribute'' for all the identifiers in the corresponding
+field declaration. The tags are available via the reflection library but
+are ignored otherwise. A tag may contain arbitrary application-specific
+information.
 
 <pre>
-var i = 0       // i has type int
-var f = 3.1415  // f has type float
+// A struct corresponding to the EventIdMessage protocol buffer.
+// The tag strings contain the protocol buffer field tags.
+struct {
+       time_usec uint64 "1";
+       server_ip uint32 "2";
+       process_id uint32 "3";
+}
 </pre>
 
-<h3>Short variable declarations</h3>
+Assignment compatibility: Structs are assignment compatible to variables of
+equal type only.
 
-A <i>short variable declaration</i> uses the syntax
 
-<pre class="grammar">
-SimpleVarDecl = IdentifierList ":=" ExpressionList .
-</pre>
+<h3>Pointer types</h3>
 
-and is shorthand for the declaration syntax
+A pointer type denotes the set of all pointers to variables of a given
+type, called the ``base type'' of the pointer, and the value "nil".
 
 <pre class="grammar">
-"var" IdentifierList = ExpressionList .
+PointerType = "*" BaseType .
+BaseType = Type .
 </pre>
 
 <pre>
-i, j := 0, 10;
-f := func() int { return 7; }
-ch := new(chan int);
+*int
+map[string] chan
 </pre>
 
-<p>
-Unlike regular variable declarations, short variable declarations
-can be used, by analogy with tuple assignment (§Assignments), to
-receive the individual elements of a multi-valued expression such
-as a call to a multi-valued function.  In this form, the ExpressionLIst
-must be a single such multi-valued expression, the number of
-identifiers must equal the number of values, and the declared
-variables will be assigned the corresponding values.
-</p>
+The pointer base type may be denoted by an identifier referring to an
+incomplete type (§Types), possibly declared via a forward declaration.
+This allows the construction of recursive and mutually recursive types
+such as:
 
 <pre>
-count, error := os.Close(fd);  // os.Close()  returns two values
+type S struct { s *S }
+
+type S2 struct // forward declaration of S2
+type S1 struct { s2 *S2 }
+type S2 struct { s1 *S1 }
 </pre>
 
+Assignment compatibility: A pointer is assignment compatible to a variable
+of pointer type, only if both types are equal.
 <p>
-Short variable declarations may appear only inside functions.
-In some contexts such as the initializers for <code>if</code>,
-<code>for</code>, or <code>switch</code> statements,
-they can be used to declare local temporary variables (§Statements).
-</p>
-
-<h3>Function declarations</h3>
-
+Comparisons: A variable of pointer type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
 <p>
-A function declaration binds an identifier to a function (§Function types).
-</p>
+Two variables of equal pointer type can be tested for equality with the
+operators "==" and "!=" (§Comparison operators). The pointers are equal
+if they point to the same location.
 
-<pre class="grammar">
-FunctionDecl = "func" identifier Signature [ Block ] .
-</pre>
+Pointer arithmetic of any kind is not permitted.
 
-<pre>
-func min(x int, y int) int {
-       if x &lt; y {
-               return x;
-       }
-       return y;
-}
-</pre>
 
-<p>
-A function must be declared or forward-declared before it can be invoked (§Forward declarations).
-Implementation restriction: Functions can only be declared at the package level.
-</p>
+<h3>Function types</h3>
 
-<h3>Method declarations</h3>
+A function type denotes the set of all functions with the same parameter
+and result types, and the value "nil".
 
-<p>
-A method declaration binds an identifier to a method,
-which is a function with a <i>receiver</i>.
-</p>
 <pre class="grammar">
-MethodDecl = "func" Receiver identifier Signature [ Block ] .
-Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
+FunctionType = "func" Signature .
+Signature = "(" [ ParameterList ] ")" [ Result ] .
+ParameterList = ParameterDecl { "," ParameterDecl } .
+ParameterDecl = [ IdentifierList ] ( Type | "..." ) .
+Result = Type | "(" ParameterList ")" .
 </pre>
 
+In ParameterList, the parameter names (IdentifierList) either must all be
+present, or all be absent. If the parameters are named, each name stands
+for one parameter of the specified type. If the parameters are unnamed, each
+type stands for one parameter of that type.
 <p>
-The receiver type must be a type name or a pointer to a type name,
-and that name is called the <i>receiver base type</i> or just <i>base type</i>.
-The base type must not be a pointer type and must be
-declared in the same source file as the method.
-The method is said to be <i>bound</i> to the base type
-and is visible only within selectors for that type
-(§Type declarations, §Selectors).
-</p>
-
-<p>
-All methods bound to a base type must have the same receiver type,
-either all pointers to the base type or all the base type itself.
-Given type <code>Point</code>, the declarations
-</p>
+For the last incoming parameter only, instead of a parameter type one
+may write "...". The ellipsis indicates that the last parameter stands
+for an arbitrary number of additional arguments of any type (including
+no additional arguments). If the parameters are named, the identifier
+list immediately preceding "..." must contain only one identifier (the
+name of the last parameter).
 
 <pre>
-func (p *Point) Length() float {
-       return Math.sqrt(p.x * p.x + p.y * p.y);
-}
+func ()
+func (x int)
+func () int
+func (string, float, ...)
+func (a, b int, z float) bool
+func (a, b int, z float) (bool)
+func (a, b int, z float, opt ...) (success bool)
+func (int, int, float) (float, *[]int)
+</pre>
 
-func (p *Point) Scale(factor float) {
-       p.x = p.x * factor;
-       p.y = p.y * factor;
-}
+If the result type of a function is itself a function type, the result type
+must be parenthesized to resolve a parsing ambiguity:
+
+<pre>
+func (n int) (func (p* T))
 </pre>
 
+Assignment compatibility: A function can be assigned to a function
+variable only if both function types are equal.
 <p>
-bind the methods <code>Length</code> and <code>Scale</code>
-to the base type <code>Point</code>.
-</p>
-
+Comparisons: A variable of function type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
 <p>
-If the
-receiver's value is not referenced inside the the body of the method,
-its identifier may be omitted in the declaration. The same applies in
-general to parameters of functions and methods.
-</p>
+Two variables of equal function type can be tested for equality with the
+operators "==" and "!=" (§Comparison operators). The variables are equal
+if they refer to the same function.
 
-<p>
-Methods can be declared
-only after their base type is declared or forward-declared, and invoked
-only after their own declaration or forward-declaration (§Forward declarations).
-Implementation restriction: They can only be declared at package level.
-</p>
 
-<h3>Forward declarations</h3>
+<h3>Interface types</h3>
 
-<p>
-Mutually-recursive types struct or interface types require that one be
-<i>forward declared</i> so that it may be named in the other.
-A forward declaration of a type omits the block containing the fields
-or methods of the type.
-</p>
+Type interfaces may be specified explicitly by interface types.
+An interface type denotes the set of all types that implement at least
+the set of methods specified by the interface type, and the value "nil".
+
+<pre class="grammar">
+InterfaceType = "interface" [ "{" [ MethodSpecList ] "}" ] .
+MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
+MethodSpec = IdentifierList Signature | TypeName .
+</pre>
 
 <pre>
-type List struct  // forward declaration of List
-type Item struct {
-       value int;
-       next *List;
-}
-type List struct {
-       head, tail *Item
+// An interface specifying a basic File type.
+interface {
+       Read, Write     (b Buffer) bool;
+       Close           ();
 }
 </pre>
-<p>
-A forward-declared type is incomplete (§Types)
-until it is fully declared. The full declaration must follow
-before the end of the block containing the forward declaration.
-</p>
-<p>
-Functions and methods may similarly be forward-declared by omitting their body.
-</p>
+
+Any type (including interface types) whose interface has, possibly as a
+subset, the complete set of methods of an interface I is said to implement
+interface I. For instance, if two types S1 and S2 have the methods
+
 <pre>
-func F(a int) int  // forward declaration of F
-func G(a, b int) int {
-       return F(a) + F(b)
-}
-func F(a int) int {
-       if a <= 0 { return 0 }
-       return G(a-1, b+1)
-}
+func (p T) Read(b Buffer) bool { return ... }
+func (p T) Write(b Buffer) bool { return ... }
+func (p T) Close() { ... }
 </pre>
 
-<hr/>
+(where T stands for either S1 or S2) then the File interface is
+implemented by both S1 and S2, regardless of what other methods
+S1 and S2 may have or share.
 
-<h2>Types</h2>
+All types implement the empty interface:
 
-A type specifies the set of values that variables of that type may assume
-and the operators that are applicable.
-<p>
-A type may be specified by a type name (§Type declarations) or a type literal.
-A type literal is a syntactic construct that explicitly specifies the
-composition of a new type in terms of other (already declared) types.
+<pre>
+interface {}
+</pre>
 
-<pre class="grammar">
-Type = TypeName | TypeLit | "(" Type ")" .
-TypeName = QualifiedIdent.
-TypeLit =
-       ArrayType | StructType | PointerType | FunctionType | InterfaceType |
-       SliceType | MapType | ChannelType .
+In general, a type implements an arbitrary number of interfaces.
+For instance, consider the interface
+
+<pre>
+type Lock interface {
+       Lock, Unlock    ();
+}
 </pre>
 
-Some types are predeclared and denoted by their type names; these are called
-``basic types''. Generally (except for strings) they are not composed of more
-elementary types; instead they model elementary machine data types.
-<p>
-All other types are called ``composite types'; they are composed from other
-(basic or composite) types and denoted by their type names or by type literals.
-There are arrays, structs, pointers, functions, interfaces, slices, maps, and
-channels.
-<p>
-At a given point in the source code, a type may be ``complete'' or
-''incomplete''. Array and struct types are complete when they are fully declared.
-All other types are always complete (although their components, such as the base
-type of a pointer type, may be incomplete). Incomplete types are subject to usage
-restrictions; for instance the type of a variable must be complete where the
-variable is declared.
+If S1 and S2 also implement
 
-The ``interface'' of a type is the set of methods bound to it
-(§Method declarations). The interface of a pointer type is the interface
-of the pointer base type (§Pointer types). All types have an interface;
-if they have no methods associated with them, their interface is
-called the ``empty'' interface.
-<p>
-The ``static type'' (or simply ``type'') of a variable is the type defined by
-the variable's declaration. The ``dynamic type'' of a variable is the actual
-type of the value stored in a variable at run-time. Except for variables of
-interface type, the dynamic type of a variable is always its static type.
+<pre>
+func (p T) Lock() { ... }
+func (p T) Unlock() { ... }
+</pre>
+
+they implement the Lock interface as well as the File interface.
 <p>
-Variables of interface type may hold values with different dynamic types
-during execution. However, its dynamic type is always compatible with
-the static type of the interface variable (§Interface types).
-       
+An interface may contain a type name T in place of a method specification.
+T must denote another, complete (and not forward-declared) interface type.
+Using this notation is equivalent to enumerating the methods of T explicitly
+in the interface containing T.
 
-<h3>Basic types</h3>
+<pre>
+type ReadWrite interface {
+       Read, Write     (b Buffer) bool;
+}
 
-Go defines a number of basic types, referred to by their predeclared
-type names.  These include traditional arithmetic types, booleans,
-and strings.
+type File interface {
+       ReadWrite;  // same as enumerating the methods in ReadWrite
+       Lock;       // same as enumerating the methods in Lock
+       Close();
+}
+</pre>
 
+Forward declaration:
+A interface type consisting of only the reserved word "interface" may be used in
+a type declaration; it declares an incomplete interface type (§Type declarations).
+This allows the construction of mutually recursive types such as:
 
-<h3>Arithmetic types</h3>
+<pre>
+type T2 interface
+type T1 interface {
+       foo(T2) int;
+}
+type T2 interface {
+       bar(T1) int;
+}
+</pre>
 
-The following list enumerates all platform-independent numeric types:
+Assignment compatibility: A value can be assigned to an interface variable
+if the static type of the value implements the interface or if the value is "nil".
+<p>
+Comparisons: A variable of interface type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
+<p>
+Two variables of interface type can be tested for equality with the
+operators "==" and "!=" (§Comparison operators) if both variables have the
+same static type. They are equal if both their dynamic types and values are
+equal. If the dynamic types are equal but the values do not support comparison,
+a run-time error occurs.
 
-<pre class="grammar">
-byte     same as uint8 (for convenience)
 
-uint8    the set of all unsigned  8-bit integers (0 to 255)
-uint16   the set of all unsigned 16-bit integers (0 to 65535)
-uint32   the set of all unsigned 32-bit integers (0 to 4294967295)
-uint64   the set of all unsigned 64-bit integers (0 to 18446744073709551615)
+<h3>Slice types</h3>
 
-int8     the set of all signed  8-bit integers (-128 to 127)
-int16    the set of all signed 16-bit integers (-32768 to 32767)
-int32    the set of all signed 32-bit integers (-2147483648 to 2147483647)
-int64    the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
+A slice type denotes the set of all slices (segments) of arrays
+(§Array types) of a given element type, and the value "nil".
+The number of elements of a slice is called its length; it is never negative.
+The elements of a slice are designated by indices which are
+integers from 0 through the length - 1.
 
-float32  the set of all valid IEEE-754 32-bit floating point numbers
-float64  the set of all valid IEEE-754 64-bit floating point numbers
+<pre class="grammar">
+SliceType = "[" "]" ElementType .
 </pre>
 
-Integer types are represented in the usual binary format; the value of
-an n-bit integer is n bits wide. A negative signed integer is represented
-as the two's complement of its absolute value.
+Syntactically and semantically, arrays and slices look and behave very
+similarly, but with one important difference: A slice is a descriptor
+of an array segment; in particular, different variables of a slice type may
+refer to different (and possibly overlapping) segments of the same underlying
+array. Thus, with respect to the underlying array, slices behave like
+references. In contrast, two different variables of array type always
+denote two different arrays.
+<p>
+For slices, the actual array underlying the slice may extend past the current
+slice length; the maximum length a slice may assume is called its capacity.
+The capacity of any slice "a" can be discovered using the built-in function
 
-<!--
-The representation of signed integers and their exact range is
-implementation-specific, but the set of all positive values (including zero)
-of a signed integer type is always a subset of the corresponding unsigned
-integer type (thus, a positive signed integer can always be converted into
-its corresponding unsigned type without loss).
--->
+<pre>
+cap(a)
+</pre>
 
-Additionally, Go declares a set of platform-specific numeric types for
-convenience:
+and the following relationship between "len()" and "cap()" holds:
 
-<pre class="grammar">
-uint     at least 32 bits, at most the size of the largest uint type
-int      at least 32 bits, at most the size of the largest int type
-float    at least 32 bits, at most the size of the largest float type
-uintptr  smallest uint type large enough to store the uninterpreted
-                bits of a pointer value
+<pre>
+0 <= len(a) <= cap(a)
 </pre>
 
-For instance, int might have the same size as int32 on a 32-bit
-architecture, or int64 on a 64-bit architecture.
-<p>
-Except for "byte", which is an alias for "uint8", all numeric types
-are different from each other to avoid portability issues. Conversions
-are required when different numeric types are mixed in an expression or assignment.
-For instance, "int32" and "int" are not the same type even though they may have
-the same size on a particular platform.
+The value of an uninitialized slice is "nil", and its length and capacity
+are 0. A new, initialized slice value for a given element type T is
+made using the built-in function "make", which takes a slice type
+and parameters specifying the length and optionally the capacity:
+
+<pre>
+make([]T, length)
+make([]T, length, capacity)
+</pre>
+       
+The "make()" call allocates a new underlying array to which the returned
+slice value refers. More precisely, calling "make"
 
+<pre>
+make([]T, length, capacity)
+</pre>
 
-<h3>Booleans</h3>
+is effectively the same as allocating an array and slicing it
 
-The type "bool" comprises the truth values true and false, which are
-available through the two predeclared constants, "true" and "false".
+<pre>
+new([capacity]T)[0 : length]
+</pre>
 
+Assignment compatibility: Slices are assignment compatible to variables
+of the same type.
+<p>
+Indexing: Given a (pointer to) a slice variable "a", a slice element is
+specified with an index operation:
 
-<h3>Strings</h3>
+<pre>
+a[i]
+</pre>
 
+This denotes the slice element at index "i". "i" must be within bounds,
+that is "0 &lt;= i &lt; len(a)".
 <p>
-The "string" type represents the set of string values (strings).
-Strings behave like arrays of bytes, with the following properties:
-</p>
-<ul>
-<li>They are immutable: after creation, it is not possible to change the
-contents of a string.
-<li>No internal pointers: it is illegal to create a pointer to an inner
-element of a string.
-<li>They can be indexed: given string "s1", "s1[i]" is a byte value.
-<li>They can be concatenated: given strings "s1" and "s2", "s1 + s2" is a value
-combining the elements of "s1" and "s2" in sequence.
-<li>Known length: the length of a string "s1" can be obtained by calling
-"len(s1)".  The length of a string is the number
-of bytes within. Unlike in C, there is no terminal NUL byte.
-<li>Creation 1: a string can be created from an integer value by a conversion;
-the result is a string containing the UTF-8 encoding of that code point
-(§Conversions).
-"string('x')" yields "x"; "string(0x1234)" yields the equivalent of "\u1234"
+Slicing: Given a a slice variable "a", a sub-slice is created with a slice
+operation:
 
-<li>Creation 2: a string can by created from an array of integer values (maybe
-just array of bytes) by a conversion (§Conversions):
 <pre>
-a [3]byte; a[0] = 'a'; a[1] = 'b'; a[2] = 'c';  string(a) == "abc";
+a[i : j]
 </pre>
-</ul>
+
+This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]"
+(that is, excluding "a[j]"). The values "i" and "j" must satisfy the condition
+"0 &lt;= i &lt;= j &lt;= cap(a)". The length of the new slice is "j - i". The capacity of
+the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change
+as a result of a slice operation. The type of a sub-slice is the same as the
+type of the slice. Unlike the capacity, the length of a sub-slice may be larger
+than the length of the original slice.
+<p>
+Comparisons: A variable of slice type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
 
 
-<h3>Array types</h3>
+<h3>Map types</h3>
 
-An array is a composite type consisting of a number of elements all of the
-same type, called the element type. The element type must be a complete type
-(§Types). The number of elements of an array is called its length; it is never
-negative. The elements of an array are designated by indices
-which are integers from 0 through the length - 1.
+A map is a composite type consisting of a variable number of entries
+called (key, value) pairs. For a given map, the keys and values must
+each be of a specific complete type (§Types) called the key and value type,
+respectively. The number of entries in a map is called its length; it is never
+negative.
 
 <pre class="grammar">
-ArrayType = "[" ArrayLength "]" ElementType .
-ArrayLength = Expression .
-ElementType = CompleteType .
+MapType = "map" "[" KeyType "]" ValueType .
+KeyType = CompleteType .
+ValueType = CompleteType .
 </pre>
 
-The array length and its value are part of the array type. The array length
-must be a constant expression (§Constant expressions) that evaluates to an
-integer value >= 0.
+The comparison operators "==" and "!=" (§Comparison operators) must be defined
+for operands of the key type; thus the key type must be a basic, pointer,
+interface, or channel type. If the key type is an interface type,
+the dynamic key types must support these comparison operators. In this case,
+inserting a map value with a key that does not support testing for equality
+is a run-time error.
 <p>
-The number of elements of an array "a" can be discovered using the built-in
-function
+Upon creation, a map is empty and values may be added and removed
+during execution.
 
 <pre>
-len(a)
+map [string] int
+map [*T] struct { x, y float }
+map [string] interface {}
 </pre>
 
-The length of arrays is known at compile-time, and the result of a call to
-"len(a)" is a compile-time constant.
+The length of a map "m" can be discovered using the built-in function
 
 <pre>
-[32]byte
-[2*N] struct { x, y int32 }
-[1000]*float64
+len(m)
 </pre>
 
-Assignment compatibility: Arrays can be assigned to variables of equal type
-and to slice variables with equal element type. When assigning to a slice
-variable, the array is not copied but a slice comprising the entire array
-is created.
+The value of an uninitialized map is "nil". A new, empty map value for given
+map type M is made using the built-in function "make" which takes the map type
+and an optional capacity as arguments:
 
+<pre>
+my_map := make(M, 100);
+</pre>
 
-<h3>Struct types</h3>
+The map capacity is an allocation hint for more efficient incremental growth
+of the map.
+<p>
+Assignment compatibility: A map type is assignment compatible to a variable of
+map type only if both types are equal.
+<p>
+Comparisons: A variable of map type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
 
-A struct is a composite type consisting of a fixed number of elements,
-called fields, with possibly different types. A struct type declares
-an identifier and type for each field. Within a struct type no field
-identifier may be declared twice and all field types must be complete
-types (§Types).
 
-<pre class="grammar">
-StructType = "struct" [ "{" [ FieldDeclList ] "}" ] .
-FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] .
-FieldDecl = (IdentifierList CompleteType | [ "*" ] TypeName) [ Tag ] .
-Tag = StringLit .
-</pre>
+<h3>Channel types</h3>
 
-<pre>
-// An empty struct.
-struct {}
+A channel provides a mechanism for two concurrently executing functions
+to synchronize execution and exchange values of a specified type. This
+type must be a complete type (§Types). <font color=red>(TODO could it be incomplete?)</font>
 
-// A struct with 5 fields.
-struct {
-       x, y int;
-       u float;
-       A *[]int;
-       F func();
-}
+<pre class="grammar">
+ChannelType = Channel | SendChannel | RecvChannel .
+Channel = "chan" ValueType .
+SendChannel = "chan" "&lt;-" ValueType .
+RecvChannel = "&lt;-" "chan" ValueType .
 </pre>
 
-A struct may contain ``anonymous fields'', which are declared with a type
-but no explicit field identifier. An anonymous field type must be specified as
-a type name "T", or as a pointer to a type name ``*T'', and T itself may not be
-a pointer or interface type. The unqualified type name acts as the field identifier.
+Upon creation, a channel can be used both to send and to receive.
+By conversion or assignment, a channel may be constrained only to send or
+to receive. This constraint is called a channel's ``direction''; either
+bi-directional (unconstrained), send, or receive.
 
 <pre>
-// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
-struct {
-       T1;        // the field name is T1
-       *T2;       // the field name is T2
-       P.T3;      // the field name is the unqualified type name T3
-       *P.T4;     // the field name is the unqualified type name T4
-       x, y int;  
-}
+chan T         // can send and receive values of type T
+chan &lt;- float  // can only be used to send floats
+&lt;-chan int     // can only receive ints
 </pre>
 
-The unqualified type name of an anonymous field must not conflict with the
-field identifier (or unqualified type name for an anonymous field) of any
-other field within the struct. The following declaration is illegal:
+The value of an uninitialized channel is "nil". A new, initialized channel
+value for a given element type T is made using the built-in function "make",
+which takes the channel type and an optional capacity as arguments:
 
 <pre>
-struct {
-       T;         // conflicts with anonymous field *T and *P.T
-       *T;        // conflicts with anonymous field T and *P.T
-       *P.T;      // conflicts with anonymous field T and *T
-}
+my_chan = make(chan int, 100);
 </pre>
 
-Fields and methods (§Method declarations) of an anonymous field become directly
-accessible as fields and methods of the struct without the need to provide the
-type name of the respective anonymous field (§Selectors).
+The capacity sets the size of the buffer in the communication channel. If the
+capacity is greater than zero, the channel is asynchronous and, provided the
+buffer is not full, sends can succeed without blocking. If the capacity is zero,
+the communication succeeds only when both a sender and receiver are ready.
 <p>
-A field declaration may be followed by an optional string literal tag which
-becomes an ``attribute'' for all the identifiers in the corresponding
-field declaration. The tags are available via the reflection library but
-are ignored otherwise. A tag may contain arbitrary application-specific
-information.
+Assignment compatibility: A value of type channel can be assigned to a variable
+of type channel only if a) both types are equal (§Type equality), or b) both
+have equal channel value types and the value is a bidirectional channel.
+<p>
+Comparisons: A variable of channel type can be compared against "nil" with the
+operators "==" and "!=" (§Comparison operators). The variable is
+"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
+if the variable has not been modified since creation (§Program initialization
+and execution).
+<p>
+Two variables of channel type can be tested for equality with the
+operators "==" and "!=" (§Comparison operators) if both variables have
+the same ValueType. They are equal if both values were created by the same
+"make" call (§Making slices, maps, and channels).
 
-<pre>
-// A struct corresponding to the EventIdMessage protocol buffer.
-// The tag strings contain the protocol buffer field tags.
-struct {
-       time_usec uint64 "1";
-       server_ip uint32 "2";
-       process_id uint32 "3";
-}
-</pre>
 
-Assignment compatibility: Structs are assignment compatible to variables of
-equal type only.
+<h3>Type equality</h3>
+
+<p>
+Types may be ``different'', ``structurally equal'', or ``identical''.
+Go is a type-safe language; generally different types cannot be mixed
+in binary operations, and values cannot be assigned to variables of different
+types. However, values may be assigned to variables of structurally
+equal types. Finally, type guards succeed only if the dynamic type
+is identical to or implements the type tested against (§Type guards).
+<p>
+Structural type equality (equality for short) is defined by these rules:
+<p>
+Two type names denote equal types if the types in the corresponding declarations
+are equal. Two type literals specify equal types if they have the same
+literal structure and corresponding components have equal types. Loosely
+speaking, two types are equal if their values have the same layout in memory.
+More precisely:
+</p>
+<ul>
+       <li>Two array types are equal if they have equal element types and if they
+         have the same array length.
 
+       <li>Two struct types are equal if they have the same number of fields in the
+         same order, corresponding fields either have both the same name or
+         are both anonymous, and corresponding field types are identical.
 
-<h3>Pointer types</h3>
+       <li>Two pointer types are equal if they have equal base types.
 
-A pointer type denotes the set of all pointers to variables of a given
-type, called the ``base type'' of the pointer, and the value "nil".
+       <li>Two function types are equal if they have the same number of parameters
+         and result values and if corresponding parameter and result types are
+         equal (a "..." parameter is equal to another "..." parameter).
+         Note that parameter and result names do not have to match.
 
-<pre class="grammar">
-PointerType = "*" BaseType .
-BaseType = Type .
-</pre>
+       <li>Two slice types are equal if they have equal element types.
 
-<pre>
-*int
-map[string] chan
-</pre>
+       <li>Two channel types are equal if they have equal value types and
+         the same direction.
 
-The pointer base type may be denoted by an identifier referring to an
-incomplete type (§Types), possibly declared via a forward declaration.
-This allows the construction of recursive and mutually recursive types
-such as:
+       <li>Two map types are equal if they have equal key and value types.
 
-<pre>
-type S struct { s *S }
+       <li>Two interface types are equal if they have the same set of methods
+         with the same names and equal function types. Note that the order
+         of the methods in the respective type declarations is irrelevant.
+</ul>
+
+<p>
+Type identity is defined by these rules:
+</p>
+<p>
+Two type names denote identical types if they originate in the same
+type declaration. Two type literals specify identical types if they have the
+same literal structure and corresponding components have identical types.
+More precisely:
+</p>
+<ul>
+       <li>Two array types are identical if they have identical element types and if
+         they have the same array length.
+
+       <li>Two struct types are identical if they have the same number of fields in
+         the same order, corresponding fields either have both the same name or
+         are both anonymous, and corresponding field types are identical.
+
+       <li>Two pointer types are identical if they have identical base types.
 
-type S2 struct // forward declaration of S2
-type S1 struct { s2 *S2 }
-type S2 struct { s1 *S1 }
-</pre>
+       <li>Two function types are identical if they have the same number of
+         parameters and result values both with the same (or absent) names, and
+         if corresponding parameter and result types are identical (a "..."
+         parameter is identical to another "..." parameter with the same name).
 
-Assignment compatibility: A pointer is assignment compatible to a variable
-of pointer type, only if both types are equal.
-<p>
-Comparisons: A variable of pointer type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
-<p>
-Two variables of equal pointer type can be tested for equality with the
-operators "==" and "!=" (§Comparison operators). The pointers are equal
-if they point to the same location.
+       <li>Two slice types are identical if they have identical element types.
 
-Pointer arithmetic of any kind is not permitted.
+       <li>Two channel types are identical if they have identical value types and
+         the same direction.
 
+       <li>Two map types are identical if they have identical key and value types.
 
-<h3>Function types</h3>
+       <li>Two interface types are identical if they have the same set of methods
+         with the same names and identical function types. Note that the order
+         of the methods in the respective type declarations is irrelevant.
+</ul>
 
-A function type denotes the set of all functions with the same parameter
-and result types, and the value "nil".
+Note that the type denoted by a type name is identical only to the type literal
+in the type name's declaration.
+<p>
+Finally, two types are different if they are not structurally equal.
+(By definition, they cannot be identical, either).
 
-<pre class="grammar">
-FunctionType = "func" Signature .
-Signature = "(" [ ParameterList ] ")" [ Result ] .
-ParameterList = ParameterDecl { "," ParameterDecl } .
-ParameterDecl = [ IdentifierList ] ( Type | "..." ) .
-Result = Type | "(" ParameterList ")" .
+For instance, given the declarations
+
+<pre>
+type (
+       T0 []string;
+       T1 []string
+       T2 struct { a, b int };
+       T3 struct { a, c int };
+       T4 func (int, float) *T0
+       T5 func (x int, y float) *[]string
+)
 </pre>
 
-In ParameterList, the parameter names (IdentifierList) either must all be
-present, or all be absent. If the parameters are named, each name stands
-for one parameter of the specified type. If the parameters are unnamed, each
-type stands for one parameter of that type.
-<p>
-For the last incoming parameter only, instead of a parameter type one
-may write "...". The ellipsis indicates that the last parameter stands
-for an arbitrary number of additional arguments of any type (including
-no additional arguments). If the parameters are named, the identifier
-list immediately preceding "..." must contain only one identifier (the
-name of the last parameter).
+these are some types that are equal
 
 <pre>
-func ()
-func (x int)
-func () int
-func (string, float, ...)
-func (a, b int, z float) bool
-func (a, b int, z float) (bool)
-func (a, b int, z float, opt ...) (success bool)
-func (int, int, float) (float, *[]int)
+T0 and T0
+T0 and []string
+T2 and T3
+T4 and T5
+T3 and struct { a int; int }
 </pre>
 
-If the result type of a function is itself a function type, the result type
-must be parenthesized to resolve a parsing ambiguity:
+and these are some types that are identical
 
 <pre>
-func (n int) (func (p* T))
+T0 and T0
+[]int and []int
+struct { a, b *T5 } and struct { a, b *T5 }
 </pre>
 
-Assignment compatibility: A function can be assigned to a function
-variable only if both function types are equal.
-<p>
-Comparisons: A variable of function type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
-<p>
-Two variables of equal function type can be tested for equality with the
-operators "==" and "!=" (§Comparison operators). The variables are equal
-if they refer to the same function.
+As an example, "T0" and "T1" are equal but not identical because they have
+different declarations.
 
+<hr/>
 
-<h3>Interface types</h3>
 
-Type interfaces may be specified explicitly by interface types.
-An interface type denotes the set of all types that implement at least
-the set of methods specified by the interface type, and the value "nil".
+<h2>Declarations and Scope</h2>
+
+<p>
+A declaration binds an identifier to a language entity such as
+a variable or function and specifies properties such as its type.
+Every identifier in a program must be declared.
+</p>
 
 <pre class="grammar">
-InterfaceType = "interface" [ "{" [ MethodSpecList ] "}" ] .
-MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
-MethodSpec = IdentifierList Signature | TypeName .
+Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
 </pre>
+               
+<p>
+The <i>scope</i> of an identifier is the extent of source text within which the
+identifier denotes the bound entity. No identifier may be declared twice in a
+single scope, but inner blocks can declare a new entity with the same
+identifier, in which case the scope created by the outer declaration excludes
+that created by the inner.
+</p>
+<p>
+There are levels of scoping in effect before each source file is compiled.
+In order from outermost to innermost:
+</p>
+<ol>
+       <li>The <i>universe</i> scope contains all predeclared identifiers.</li>
+       <li>An implicit scope contains only the package name.</li>
+       <li>The <i>package-level</i> scope surrounds all declarations at the
+           top level of the file, that is, outside the body of any
+           function or method.  That scope is shared across all
+           source files within the package (§Packages), allowing
+           package-level identifiers to be shared between source
+           files.</li>
+</ol>
 
-<pre>
-// An interface specifying a basic File type.
-interface {
-       Read, Write     (b Buffer) bool;
-       Close           ();
-}
-</pre>
+<p>
+The scope of an identifier depends on the entity declared:
+</p>
 
-Any type (including interface types) whose interface has, possibly as a
-subset, the complete set of methods of an interface I is said to implement
-interface I. For instance, if two types S1 and S2 have the methods
+<ol>
+       <li> The scope of predeclared identifiers is the universe scope.</li>
 
-<pre>
-func (p T) Read(b Buffer) bool { return ... }
-func (p T) Write(b Buffer) bool { return ... }
-func (p T) Close() { ... }
-</pre>
+       <li> The scope of an (identifier denoting a) type, function or package
+            extends from the point of the identifier in the declaration
+            to the end of the innermost surrounding block.</li>
 
-(where T stands for either S1 or S2) then the File interface is
-implemented by both S1 and S2, regardless of what other methods
-S1 and S2 may have or share.
+       <li> The scope of a constant or variable extends textually from
+            the end of the declaration to the end of the innermost
+            surrounding block. If the variable is declared in the
+            <i>init</i> statement of an <code>if </code>,  <code>for</code>,
+            or  <code>switch </code> statement, the
+            innermost surrounding block is the block associated
+            with that statement.</li>
 
-All types implement the empty interface:
+       <li> The scope of a parameter or result is the body of the
+            corresponding function.</li>
 
-<pre>
-interface {}
-</pre>
+       <li> The scope of a field or method is selectors for the
+            corresponding type containing the field or method (§Selectors).</li>
 
-In general, a type implements an arbitrary number of interfaces.
-For instance, consider the interface
+       <li> The scope of a label is a unique scope emcompassing
+            the body of the innermost surrounding function, excluding
+            nested functions.  Labels do not conflict with variables.</li>
+</ol>
 
-<pre>
-type Lock interface {
-       Lock, Unlock    ();
-}
-</pre>
+<h3>Predeclared identifiers</h3>
 
-If S1 and S2 also implement
+<p>
+The following identifiers are implicitly declared in the outermost scope:
+</p>
+<pre class="grammar">
+Basic types:
+       bool byte float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64
 
-<pre>
-func (p T) Lock() { ... }
-func (p T) Unlock() { ... }
-</pre>
+Platform-specific convenience types:
+       float int uint uintptr
 
-they implement the Lock interface as well as the File interface.
-<p>
-An interface may contain a type name T in place of a method specification.
-T must denote another, complete (and not forward-declared) interface type.
-Using this notation is equivalent to enumerating the methods of T explicitly
-in the interface containing T.
+Constants:
+       true false iota nil
 
-<pre>
-type ReadWrite interface {
-       Read, Write     (b Buffer) bool;
-}
+Functions:
+       cap convert len make new panic panicln print println typeof (TODO: typeof??)
 
-type File interface {
-       ReadWrite;  // same as enumerating the methods in ReadWrite
-       Lock;       // same as enumerating the methods in Lock
-       Close();
-}
+Packages:
+       sys unsafe  (TODO: does sys endure?)
 </pre>
 
-Forward declaration:
-A interface type consisting of only the reserved word "interface" may be used in
-a type declaration; it declares an incomplete interface type (§Type declarations).
-This allows the construction of mutually recursive types such as:
 
-<pre>
-type T2 interface
-type T1 interface {
-       foo(T2) int;
-}
-type T2 interface {
-       bar(T1) int;
-}
-</pre>
+<h3>Exported identifiers</h3>
 
-Assignment compatibility: A value can be assigned to an interface variable
-if the static type of the value implements the interface or if the value is "nil".
 <p>
-Comparisons: A variable of interface type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
+By default, identifiers are visible only within the package in which they are declared.
+Some identifiers are <i>exported</i> and can be referenced using
+<i>qualified identifiers</i> in other packages (§Qualified identifiers).
+If an identifier satisfies these two conditions:
+</p>
+<ol>
+<li>the first character of the identifier's name is a Unicode upper case letter;
+<li>the identifier is declared at the package level or is a field or method of a type
+declared at the top level;
+</ol>
 <p>
-Two variables of interface type can be tested for equality with the
-operators "==" and "!=" (§Comparison operators) if both variables have the
-same static type. They are equal if both their dynamic types and values are
-equal. If the dynamic types are equal but the values do not support comparison,
-a run-time error occurs.
-
+it will be exported automatically.
+</p>
 
-<h3>Slice types</h3>
+<h3>Const declarations</h3>
 
-A slice type denotes the set of all slices (segments) of arrays
-(§Array types) of a given element type, and the value "nil".
-The number of elements of a slice is called its length; it is never negative.
-The elements of a slice are designated by indices which are
-integers from 0 through the length - 1.
+<p>
+A constant declaration binds a list of identifiers (the names of
+the constants) to the values of a list of constant expressions
+(§Constant expressions).  The number of identifiers must be equal
+to the number of expressions, and the n<sup>th</sup> identifier on
+the left is bound to value of the n<sup>th</sup> expression on the
+right.
+</p>
 
 <pre class="grammar">
-SliceType = "[" "]" ElementType .
-</pre>
+ConstDecl      = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) .
+ConstSpecList  = ConstSpec { ";" ConstSpec } [ ";" ] .
+ConstSpec      = IdentifierList [ CompleteType ] [ "=" ExpressionList ] .
 
-Syntactically and semantically, arrays and slices look and behave very
-similarly, but with one important difference: A slice is a descriptor
-of an array segment; in particular, different variables of a slice type may
-refer to different (and possibly overlapping) segments of the same underlying
-array. Thus, with respect to the underlying array, slices behave like
-references. In contrast, two different variables of array type always
-denote two different arrays.
-<p>
-For slices, the actual array underlying the slice may extend past the current
-slice length; the maximum length a slice may assume is called its capacity.
-The capacity of any slice "a" can be discovered using the built-in function
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
 
-<pre>
-cap(a)
+CompleteType = Type .
 </pre>
 
-and the following relationship between "len()" and "cap()" holds:
+<p>
+If the type (CompleteType) is omitted, the constants take the
+individual types of the corresponding expressions, which may be
+``ideal integer'' or ``ideal float'' (§Ideal number).  If the type
+is present, all constants take the type specified, and the types
+of all the expressions must be assignment-compatible
+with that type.
+</p>
 
 <pre>
-0 <= len(a) <= cap(a)
+const Pi float64 = 3.14159265358979323846
+const E = 2.718281828
+const (
+       size int64 = 1024;
+       eof = -1;
+)
+const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo"
+const u, v float = 0, 3      // u = 0.0, v = 3.0
 </pre>
 
-The value of an uninitialized slice is "nil", and its length and capacity
-are 0. A new, initialized slice value for a given element type T is
-made using the built-in function "make", which takes a slice type
-and parameters specifying the length and optionally the capacity:
-
-<pre>
-make([]T, length)
-make([]T, length, capacity)
-</pre>
-       
-The "make()" call allocates a new underlying array to which the returned
-slice value refers. More precisely, calling "make"
+<p>
+Within a parenthesized <code>const</code> declaration list the
+expression list may be omitted from any but the first declaration.
+Such an empty list is equivalent to the textual substitution of the
+first preceding non-empty expression list.  Omitting the list of
+expressions is therefore equivalent to repeating the previous list.
+The number of identifiers must be equal to the number of expressions
+in the previous list.  Together with the <code>iota</code> constant generator
+(§Iota) this mechanism permits light-weight declaration of sequential values:
+</p>
 
 <pre>
-make([]T, length, capacity)
+const (
+       Sunday = iota;
+       Monday;
+       Tuesday;
+       Wednesday;
+       Thursday;
+       Friday;
+       Partyday;
+       numberOfDays;  // this constant is not exported
+)
 </pre>
 
-is effectively the same as allocating an array and slicing it
 
-<pre>
-new([capacity]T)[0 : length]
-</pre>
+<h3>Iota</h3>
 
-Assignment compatibility: Slices are assignment compatible to variables
-of the same type.
 <p>
-Indexing: Given a (pointer to) a slice variable "a", a slice element is
-specified with an index operation:
+Within a constant declaration, the predeclared pseudo-constant
+<code>iota</code> represents successive integers. It is reset to 0
+whenever the reserved word <code>const</code> appears in the source
+and increments with each semicolon. It can be used to construct a
+set of related constants:
+</p>
 
 <pre>
-a[i]
+const (            // iota is reset to 0
+       c0 = iota;  // c0 == 0
+       c1 = iota;  // c1 == 1
+       c2 = iota   // c2 == 2
+)
+
+const (
+       a = 1 << iota;  // a == 1 (iota has been reset)
+       b = 1 << iota;  // b == 2
+       c = 1 << iota;  // c == 4
+)
+
+const (
+       u       = iota * 42;  // u == 0     (ideal integer)
+       v float = iota * 42;  // v == 42.0  (float)
+       w       = iota * 42;  // w == 84    (ideal integer)
+)
+
+const x = iota;  // x == 0 (iota has been reset)
+const y = iota;  // y == 0 (iota has been reset)
 </pre>
 
-This denotes the slice element at index "i". "i" must be within bounds,
-that is "0 &lt;= i &lt; len(a)".
 <p>
-Slicing: Given a a slice variable "a", a sub-slice is created with a slice
-operation:
+Within an ExpressionList, the value of each <code>iota</code> is the same because
+it is only incremented at a semicolon:
+</p>
 
 <pre>
-a[i : j]
+const (
+       bit0, mask0 = 1 << iota, 1 << iota - 1;  // bit0 == 1, mask0 == 0
+       bit1, mask1;                             // bit1 == 2, mask1 == 1
+       bit2, mask2;                             // bit2 == 4, mask2 == 3
+)
 </pre>
 
-This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]"
-(that is, excluding "a[j]"). The values "i" and "j" must satisfy the condition
-"0 &lt;= i &lt;= j &lt;= cap(a)". The length of the new slice is "j - i". The capacity of
-the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change
-as a result of a slice operation. The type of a sub-slice is the same as the
-type of the slice. Unlike the capacity, the length of a sub-slice may be larger
-than the length of the original slice.
 <p>
-Comparisons: A variable of slice type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
+This last example exploits the implicit repetition of the
+last non-empty expression list.
+</p>
 
 
-<h3>Map types</h3>
+<h3>Type declarations</h3>
 
-A map is a composite type consisting of a variable number of entries
-called (key, value) pairs. For a given map, the keys and values must
-each be of a specific complete type (§Types) called the key and value type,
-respectively. The number of entries in a map is called its length; it is never
-negative.
+<p>
+A type declaration binds an identifier, the <i>type name</i>,
+to a new type.  <font color=red>TODO: what exactly is a "new type"?</font>
+</p>
 
 <pre class="grammar">
-MapType = "map" "[" KeyType "]" ValueType .
-KeyType = CompleteType .
-ValueType = CompleteType .
+TypeDecl     = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) .
+TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
+TypeSpec     = identifier Type .
 </pre>
 
-The comparison operators "==" and "!=" (§Comparison operators) must be defined
-for operands of the key type; thus the key type must be a basic, pointer,
-interface, or channel type. If the key type is an interface type,
-the dynamic key types must support these comparison operators. In this case,
-inserting a map value with a key that does not support testing for equality
-is a run-time error.
-<p>
-Upon creation, a map is empty and values may be added and removed
-during execution.
-
 <pre>
-map [string] int
-map [*T] struct { x, y float }
-map [string] interface {}
-</pre>
+type IntArray [16] int
 
-The length of a map "m" can be discovered using the built-in function
+type (
+       Point struct { x, y float };
+       Polar Point
+)
 
-<pre>
-len(m)
+type TreeNode struct {
+       left, right *TreeNode;
+       value Point;
+}
+
+type Comparable interface {
+       cmp(Comparable) int
+}
 </pre>
 
-The value of an uninitialized map is "nil". A new, empty map value for given
-map type M is made using the built-in function "make" which takes the map type
-and an optional capacity as arguments:
+<h3>Variable declarations</h3>
+
+<p>
+A variable declaration creates a variable, binds an identifier to it and
+gives it a type and optionally an initial value.
+The variable type must be a complete type (§Types).
+</p>
+<pre class="grammar">
+VarDecl     = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) .
+VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
+VarSpec     = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
+</pre>
 
 <pre>
-my_map := make(M, 100);
+var i int
+var U, V, W float
+var k = 0
+var x, y float = -1.0, -2.0
+var (
+       i int;
+       u, v, s = 2.0, 3.0, "bar"
+)
 </pre>
 
-The map capacity is an allocation hint for more efficient incremental growth
-of the map.
 <p>
-Assignment compatibility: A map type is assignment compatible to a variable of
-map type only if both types are equal.
+If there are expressions, their number must be equal
+to the number of identifiers, and the n<sup>th</sup> variable
+is initialized to the value of the n<sup>th</sup> expression.
+Otherwise, each variable is initialized to the <i>zero</i>
+of the type (§Program initialization and execution).
+The expressions can be general expressions; they need not be constants.
+</p>
 <p>
-Comparisons: A variable of map type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
+Either the type or the expression list must be present.  If the
+type is present, it sets the type of each variable and the expressions
+(if any) must be assignment-compatible to that type.  If the type
+is absent, the variables take the types of the corresponding
+expressions.
+</p>
+<p>
+If the type is absent and the corresponding expression is a constant
+expression of ideal integer or ideal float type, the type of the
+declared variable is <code>int</code> or <code>float</code>
+respectively:
+</p>
 
+<pre>
+var i = 0       // i has type int
+var f = 3.1415  // f has type float
+</pre>
 
-<h3>Channel types</h3>
+<h3>Short variable declarations</h3>
 
-A channel provides a mechanism for two concurrently executing functions
-to synchronize execution and exchange values of a specified type. This
-type must be a complete type (§Types). <font color=red>(TODO could it be incomplete?)</font>
+A <i>short variable declaration</i> uses the syntax
 
 <pre class="grammar">
-ChannelType = Channel | SendChannel | RecvChannel .
-Channel = "chan" ValueType .
-SendChannel = "chan" "&lt;-" ValueType .
-RecvChannel = "&lt;-" "chan" ValueType .
+SimpleVarDecl = IdentifierList ":=" ExpressionList .
 </pre>
 
-Upon creation, a channel can be used both to send and to receive.
-By conversion or assignment, a channel may be constrained only to send or
-to receive. This constraint is called a channel's ``direction''; either
-bi-directional (unconstrained), send, or receive.
+and is shorthand for the declaration syntax
 
-<pre>
-chan T         // can send and receive values of type T
-chan &lt;- float  // can only be used to send floats
-&lt;-chan int     // can only receive ints
+<pre class="grammar">
+"var" IdentifierList = ExpressionList .
 </pre>
 
-The value of an uninitialized channel is "nil". A new, initialized channel
-value for a given element type T is made using the built-in function "make",
-which takes the channel type and an optional capacity as arguments:
-
 <pre>
-my_chan = make(chan int, 100);
+i, j := 0, 10;
+f := func() int { return 7; }
+ch := new(chan int);
 </pre>
 
-The capacity sets the size of the buffer in the communication channel. If the
-capacity is greater than zero, the channel is asynchronous and, provided the
-buffer is not full, sends can succeed without blocking. If the capacity is zero,
-the communication succeeds only when both a sender and receiver are ready.
-<p>
-Assignment compatibility: A value of type channel can be assigned to a variable
-of type channel only if a) both types are equal (§Type equality), or b) both
-have equal channel value types and the value is a bidirectional channel.
-<p>
-Comparisons: A variable of channel type can be compared against "nil" with the
-operators "==" and "!=" (§Comparison operators). The variable is
-"nil" only if "nil" is assigned explicitly to the variable (§Assignments), or
-if the variable has not been modified since creation (§Program initialization
-and execution).
 <p>
-Two variables of channel type can be tested for equality with the
-operators "==" and "!=" (§Comparison operators) if both variables have
-the same ValueType. They are equal if both values were created by the same
-"make" call (§Making slices, maps, and channels).
-
+Unlike regular variable declarations, short variable declarations
+can be used, by analogy with tuple assignment (§Assignments), to
+receive the individual elements of a multi-valued expression such
+as a call to a multi-valued function.  In this form, the ExpressionLIst
+must be a single such multi-valued expression, the number of
+identifiers must equal the number of values, and the declared
+variables will be assigned the corresponding values.
+</p>
 
-<h3>Type equality</h3>
+<pre>
+count, error := os.Close(fd);  // os.Close()  returns two values
+</pre>
 
 <p>
-Types may be ``different'', ``structurally equal'', or ``identical''.
-Go is a type-safe language; generally different types cannot be mixed
-in binary operations, and values cannot be assigned to variables of different
-types. However, values may be assigned to variables of structurally
-equal types. Finally, type guards succeed only if the dynamic type
-is identical to or implements the type tested against (§Type guards).
-<p>
-Structural type equality (equality for short) is defined by these rules:
-<p>
-Two type names denote equal types if the types in the corresponding declarations
-are equal. Two type literals specify equal types if they have the same
-literal structure and corresponding components have equal types. Loosely
-speaking, two types are equal if their values have the same layout in memory.
-More precisely:
+Short variable declarations may appear only inside functions.
+In some contexts such as the initializers for <code>if</code>,
+<code>for</code>, or <code>switch</code> statements,
+they can be used to declare local temporary variables (§Statements).
 </p>
-<ul>
-       <li>Two array types are equal if they have equal element types and if they
-         have the same array length.
 
-       <li>Two struct types are equal if they have the same number of fields in the
-         same order, corresponding fields either have both the same name or
-         are both anonymous, and corresponding field types are identical.
-
-       <li>Two pointer types are equal if they have equal base types.
+<h3>Function declarations</h3>
 
-       <li>Two function types are equal if they have the same number of parameters
-         and result values and if corresponding parameter and result types are
-         equal (a "..." parameter is equal to another "..." parameter).
-         Note that parameter and result names do not have to match.
+<p>
+A function declaration binds an identifier to a function (§Function types).
+</p>
 
-       <li>Two slice types are equal if they have equal element types.
+<pre class="grammar">
+FunctionDecl = "func" identifier Signature [ Block ] .
+</pre>
 
-       <li>Two channel types are equal if they have equal value types and
-         the same direction.
+<pre>
+func min(x int, y int) int {
+       if x &lt; y {
+               return x;
+       }
+       return y;
+}
+</pre>
 
-       <li>Two map types are equal if they have equal key and value types.
+<p>
+A function must be declared or forward-declared before it can be invoked (§Forward declarations).
+Implementation restriction: Functions can only be declared at the package level.
+</p>
 
-       <li>Two interface types are equal if they have the same set of methods
-         with the same names and equal function types. Note that the order
-         of the methods in the respective type declarations is irrelevant.
-</ul>
+<h3>Method declarations</h3>
 
 <p>
-Type identity is defined by these rules:
+A method declaration binds an identifier to a method,
+which is a function with a <i>receiver</i>.
 </p>
+<pre class="grammar">
+MethodDecl = "func" Receiver identifier Signature [ Block ] .
+Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
+</pre>
+
 <p>
-Two type names denote identical types if they originate in the same
-type declaration. Two type literals specify identical types if they have the
-same literal structure and corresponding components have identical types.
-More precisely:
+The receiver type must be a type name or a pointer to a type name,
+and that name is called the <i>receiver base type</i> or just <i>base type</i>.
+The base type must not be a pointer type and must be
+declared in the same source file as the method.
+The method is said to be <i>bound</i> to the base type
+and is visible only within selectors for that type
+(§Type declarations, §Selectors).
 </p>
-<ul>
-       <li>Two array types are identical if they have identical element types and if
-         they have the same array length.
-
-       <li>Two struct types are identical if they have the same number of fields in
-         the same order, corresponding fields either have both the same name or
-         are both anonymous, and corresponding field types are identical.
-
-       <li>Two pointer types are identical if they have identical base types.
-
-       <li>Two function types are identical if they have the same number of
-         parameters and result values both with the same (or absent) names, and
-         if corresponding parameter and result types are identical (a "..."
-         parameter is identical to another "..." parameter with the same name).
 
-       <li>Two slice types are identical if they have identical element types.
+<p>
+All methods bound to a base type must have the same receiver type,
+either all pointers to the base type or all the base type itself.
+Given type <code>Point</code>, the declarations
+</p>
 
-       <li>Two channel types are identical if they have identical value types and
-         the same direction.
+<pre>
+func (p *Point) Length() float {
+       return Math.sqrt(p.x * p.x + p.y * p.y);
+}
 
-       <li>Two map types are identical if they have identical key and value types.
+func (p *Point) Scale(factor float) {
+       p.x = p.x * factor;
+       p.y = p.y * factor;
+}
+</pre>
 
-       <li>Two interface types are identical if they have the same set of methods
-         with the same names and identical function types. Note that the order
-         of the methods in the respective type declarations is irrelevant.
-</ul>
+<p>
+bind the methods <code>Length</code> and <code>Scale</code>
+to the base type <code>Point</code>.
+</p>
 
-Note that the type denoted by a type name is identical only to the type literal
-in the type name's declaration.
 <p>
-Finally, two types are different if they are not structurally equal.
-(By definition, they cannot be identical, either).
+If the
+receiver's value is not referenced inside the the body of the method,
+its identifier may be omitted in the declaration. The same applies in
+general to parameters of functions and methods.
+</p>
 
-For instance, given the declarations
+<p>
+Methods can be declared
+only after their base type is declared or forward-declared, and invoked
+only after their own declaration or forward-declaration (§Forward declarations).
+Implementation restriction: They can only be declared at package level.
+</p>
 
-<pre>
-type (
-       T0 []string;
-       T1 []string
-       T2 struct { a, b int };
-       T3 struct { a, c int };
-       T4 func (int, float) *T0
-       T5 func (x int, y float) *[]string
-)
-</pre>
+<h3>Forward declarations</h3>
 
-these are some types that are equal
+<p>
+Mutually-recursive types struct or interface types require that one be
+<i>forward declared</i> so that it may be named in the other.
+A forward declaration of a type omits the block containing the fields
+or methods of the type.
+</p>
 
 <pre>
-T0 and T0
-T0 and []string
-T2 and T3
-T4 and T5
-T3 and struct { a int; int }
+type List struct  // forward declaration of List
+type Item struct {
+       value int;
+       next *List;
+}
+type List struct {
+       head, tail *Item
+}
 </pre>
-
-and these are some types that are identical
-
+<p>
+A forward-declared type is incomplete (§Types)
+until it is fully declared. The full declaration must follow
+before the end of the block containing the forward declaration.
+</p>
+<p>
+Functions and methods may similarly be forward-declared by omitting their body.
+</p>
 <pre>
-T0 and T0
-[]int and []int
-struct { a, b *T5 } and struct { a, b *T5 }
+func F(a int) int  // forward declaration of F
+func G(a, b int) int {
+       return F(a) + F(b)
+}
+func F(a int) int {
+       if a <= 0 { return 0 }
+       return G(a-1, b+1)
+}
 </pre>
 
-As an example, "T0" and "T1" are equal but not identical because they have
-different declarations.
-
 <hr/>
 
 <h2>Expressions</h2>