<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of May 4, 2011 -->
+<!-- subtitle Version of May 12, 2011 -->
<!--
TODO
<p>
The initial capacity does not bound its size:
maps grow to accommodate the number of items
-stored in them.
-</p>
+stored in them, with the exception of <code>nil</code> maps.
+A <code>nil</code> map is equivalent to an empty map except that no elements
+may be added.
+</code>
<h3 id="Channel_types">Channel types</h3>
and elements are received in the order they are sent.
If the capacity is zero or absent, the communication succeeds only when both a sender and
receiver are ready.
+A <code>nil</code> channel is never ready for communication.
</p>
<p>
math.Sin
</pre>
-<!---
+<!--
<p>
<span class="alert">TODO: Unify this section with Selectors - it's the same syntax.</span>
</p>
</pre>
-<!---
+<!--
<span class="alert">
TODO: Specify what happens to receivers.
</span>
<li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li>
<li><code>a[x]</code> is the array element at index <code>x</code> and the type of
<code>a[x]</code> is the element type of <code>A</code></li>
- <li>if the index <code>x</code> is out of range,
+ <li>if <code>a</code> is <code>nil</code> or if the index <code>x</code> is out of range,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
</ul>
<li>if the map contains an entry with key <code>x</code>,
<code>a[x]</code> is the map value with key <code>x</code>
and the type of <code>a[x]</code> is the value type of <code>M</code></li>
- <li>if the map does not contain such an entry,
+ <li>if the map is <code>nil</code> or does not contain such an entry,
<code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
for the value type of <code>M</code></li>
</ul>
</p>
<p>
-Similarly, if an assignment to a map has the special form
+Similarly, if an assignment to a map element has the special form
</p>
<pre>
a regular assignment to an element of the map.
</p>
+<p>
+Assigning to an element of a <code>nil</code> map causes a
+<a href="#Run_time_panics">run-time panic</a>.
+</p>
+
<h3 id="Slices">Slices</h3>
the value of the receive operation <code><-ch</code> is the value received
from the channel <code>ch</code>. The type of the value is the element type of
the channel. The expression blocks until a value is available.
+Receiving from a <code>nil</code> channel blocks forever.
</p>
<pre>
because the channel is closed and empty (<code>false</code>).
</p>
-<p>
-Receiving from a <code>nil</code> channel causes a
-<a href="#Run_time_panics">run-time panic</a>.
-</p>
-
-<!---
+<!--
<p>
<span class="alert">TODO: Probably in a separate section, communication semantics
need to be presented regarding send, receive, select, and goroutines.</span>
^int8(1) // same as -1 ^ int8(1) = -2
</pre>
-<!---
+<!--
<p>
<span class="alert">
TODO: perhaps ^ should be disallowed on non-uints instead of assuming twos complement.
value is transmitted on the channel.
A send on an unbuffered channel can proceed if a receiver is ready.
A send on a buffered channel can proceed if there is room in the buffer.
+A send on a <code>nil</code> channel blocks forever.
</p>
<pre>
ch <- 3
</pre>
-<p>
-Sending to a <code>nil</code> channel causes a
-<a href="#Run_time_panics">run-time panic</a>.
-</p>
-
<h3 id="IncDec_statements">IncDec statements</h3>
<a href="#Address_operators">addressable</a> or map index expressions; they
denote the iteration variables. If the range expression is a channel, only
one iteration variable is permitted, otherwise there may be one or two.
+If the second iteration variable is the <a href="#Blank_identifier">blank identifier</a>,
+the range clause is equivalent to the same clause with only the first variable present.
</p>
<p>
-The range expression is evaluated once before beginning the loop.
+The range expression is evaluated once before beginning the loop
+except if the expression is an array, in which case, depending on
+the expression, it might not be evaluated (see below).
Function calls on the left are evaluated once per iteration.
For each iteration, iteration values are produced as follows:
</p>
<ol>
<li>
-For an array or slice value, the index iteration values are produced in
-increasing order, starting at element index 0.
+For an array, pointer to array, or slice value <code>a</code>, the index iteration
+values are produced in increasing order, starting at element index 0. As a special
+case, if only the first iteration variable is present, the range loop produces
+iteration values from 0 up to <code>len(a)</code> and does not index into the array
+or slice itself. For a <code>nil</code> slice, the number of iterations is 0.
</li>
<li>
If map entries that have not yet been reached are deleted during iteration,
the corresponding iteration values will not be produced. If map entries are
inserted during iteration, the behavior is implementation-dependent, but the
-iteration values for each entry will be produced at most once.
+iteration values for each entry will be produced at most once. If the map
+is <code>nil</code>, the number of iterations is 0.
</li>
<li>
For channels, the iteration values produced are the successive values sent on
-the channel until the channel is closed
-(§<a href="#Close"><code>close</code></a>).
+the channel until the channel is <a href="#Close">closed</a>. If the channel
+is <code>nil</code>, the range expression blocks forever.
</li>
</ol>
</p>
<pre>
+var testdata *struct {
+ a *[7]int
+}
+for i, _ := range testdata.a {
+ // testdata.a is never evaluated; len(testdata.a) is constant
+ // i ranges from 0 to 6
+ f(i)
+}
+
var a [10]string
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
-
for i, s := range a {
// type of i is int
// type of s is string
}
// key == last map key encountered in iteration
// val == map[key]
+
+var ch chan Work = producer()
+for w := range ch {
+ doWork(w)
+}
</pre>
Regardless of how they are declared, all the result values are initialized to the zero values for their type (§<a href="#The_zero_value">The zero value</a>) upon entry to the function.
</p>
-<!---
+<!--
<p>
<span class="alert">
TODO: Define when return is required.<br />
<p>
is erroneous because the jump to label <code>L</code> skips
the creation of <code>v</code>.
-<!---
+<!--
(<span class="alert">TODO: Eliminate in favor of used and not set errors?</span>)
-->
</p>
</p>
<pre class="grammar">
-Call Argument type Result
+Call Argument type Result
-len(s) string type string length in bytes
- [n]T, *[n]T array length (== n)
- []T slice length
- map[K]T map length (number of defined keys)
- chan T number of elements queued in channel buffer
+len(s) string type string length in bytes
+ [n]T, *[n]T array length (== n)
+ []T slice length
+ map[K]T map length (number of defined keys)
+ chan T number of elements queued in channel buffer
-cap(s) [n]T, *[n]T array length (== n)
- []T slice capacity
- chan T channel buffer capacity
+cap(s) [n]T, *[n]T array length (== n)
+ []T slice capacity
+ chan T channel buffer capacity
</pre>
<p>
</p>
<p>
-The expression
-<code>len(s)</code> is a
-<a href="#Constants">constant</a> if <code>s</code> is a string constant.
-The expressions
-<code>len(s)</code> and
-<code>cap(s)</code> are
-constants if <code>s</code> is an (optionally parenthesized)
-identifier or
-<a href="#Qualified_identifiers">qualified identifier</a>
-denoting an array or pointer to array.
-Otherwise invocations of <code>len</code> and <code>cap</code> are not
-constant.
+The expression <code>len(s)</code> is <a href="#Constants">constant</a> if
+<code>s</code> is a string constant. The expressions <code>len(s)</code> and
+<code>cap(s)</code> are constants if the type of <code>s</code> is an array
+or pointer to an array and the expression <code>s</code> does not contain
+<a href="#Receive_operator">channel receives</a> or
+<a href="#Calls">function calls</a>; in this case <code>s</code> is not evaluated.
+Otherwise, invocations of <code>len</code> and <code>cap</code> are not
+constant and <code>s</code> is evaluated.
</p>
+
<h3 id="Allocation">Allocation</h3>
<p>
<h2 id="Implementation_differences"><span class="alert">Implementation differences - TODO</span></h2>
<ul>
- <li><span class="alert">Implementation does not honor the restriction on goto statements and targets (no intervening declarations).</span></li>
+ <li><span class="alert">The restriction on <code>goto</code> statements and targets (no intervening declarations) is not honored.</span></li>
+ <li><span class="alert"><code>len(a)</code> is only a constant if <code>a</code> is a (qualified) identifier denoting an array or pointer to an array.</span></li>
+ <li><span class="alert"><code>nil</code> maps are not treated like empty maps.</span></li>
+ <li><span class="alert">Trying to send/receive from a <code>nil</code> channel causes a run-time panic.</span></li>
</ul>