<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of January 27, 2011 -->
+<!-- subtitle Version of February 1, 2011 -->
<!--
TODO
Expression = UnaryExpr | Expression binary_op UnaryExpr .
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
-binary_op = log_op | com_op | rel_op | add_op | mul_op .
-log_op = "||" | "&&" .
-com_op = "<-" .
+binary_op = "||" | "&&" | rel_op | add_op | mul_op .
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
add_op = "+" | "-" | "|" | "^" .
mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
outside the operator hierarchy.
As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>.
<p>
-There are six precedence levels for binary operators.
+There are five precedence levels for binary operators.
Multiplication operators bind strongest, followed by addition
-operators, comparison operators, <code><-</code> (channel send),
-<code>&&</code> (logical and), and finally <code>||</code> (logical or):
+operators, comparison operators, <code>&&</code> (logical and),
+and finally <code>||</code> (logical or):
</p>
<pre class="grammar">
Precedence Operator
- 6 * / % << >> & &^
- 5 + - | ^
- 4 == != < <= > >=
- 3 <-
+ 5 * / % << >> & &^
+ 4 + - | ^
+ 3 == != < <= > >=
2 &&
1 ||
</pre>
*pf(x)
</pre>
-<h3 id="Communication_operators">Communication operators</h3>
-<p>
-The term <i>channel</i> means "value of <a href="#Channel_types">channel type</a>".
-</p>
-<p>
-The send operation uses the binary operator "<-", which operates on
-a channel and a value (expression):
-</p>
-
-<pre>
-ch <- 3
-</pre>
+<h3 id="Receive_operator">Receive operator</h3>
<p>
-The send operation sends the value on the channel. Both the channel
-and the expression are evaluated before communication begins.
-Communication blocks until the send can proceed, at which point the
-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.
-</p>
-
-<p>
-The receive operation uses the prefix unary operator "<-".
-The value of the expression is the value received, whose type
-is the element type of the channel.
-</p>
-
-<pre>
-<-ch
-</pre>
-
-<p>
-The expression blocks until a value is available, which then can
-be assigned to a variable or used like any other expression.
-If the receive expression does not save the value, the value is
-discarded.
+For an operand <code>ch</code> of <a href="#Channel_types">channel type</a>,
+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.
</p>
<pre>
v1 := <-ch
v2 = <-ch
f(<-ch)
-<-strobe // wait until clock pulse
+<-strobe // wait until clock pulse and discard received value
</pre>
<!--
-->
<p>
-Except in a communications clause of a <a href="#Select_statements">select statement</a>,
-sending or receiving from a <code>nil</code> channel causes a
+Receiving from a <code>nil</code> channel causes a
<a href="#Run_time_panics">run-time panic</a>.
</p>
</p>
--->
+
<h3 id="Method_expressions">Method expressions</h3>
<p>
FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
DeferStmt .
-SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl .
+SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
</pre>
<h3 id="Expression_statements">Expression statements</h3>
<p>
-Function calls, method calls, and channel operations
+Function calls, method calls, and receive operations
can appear in statement context.
</p>
</pre>
<pre>
-f(x+y)
+h(x+y)
+f.Close()
<-ch
</pre>
+<h3 id="Send_statements">Send statements</h3>
+
+<p>
+A send statement sends a value on a channel.
+The channel expression must be of <a href="#Channel_types">channel type</a>
+and the type of the value must be <a href="#Assignability">assignable</a>
+to the channel's element type.
+</p>
+
+<pre class="ebnf">
+SendStmt = Channel "<-" Expression .
+Channel = Expression .
+</pre>
+
+<p>
+Both the channel and the value expression are evaluated before communication
+begins. Communication blocks until the send can proceed, at which point the
+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.
+</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>
<p>
<pre class="ebnf">
SelectStmt = "select" "{" { CommClause } "}" .
CommClause = CommCase ":" { Statement ";" } .
-CommCase = "case" ( SendExpr | RecvExpr) | "default" .
-SendExpr = Expression "<-" Expression .
-RecvExpr = [ Expression ( "=" | ":=" ) ] "<-" Expression .
+CommCase = "case" ( SendStmt | RecvStmt ) | "default" .
+RecvStmt = [ Expression ( "=" | ":=" ) ] RecvExpr .
+RecvExpr = Expression .
</pre>
<!-- TODO(rsc):
-RecvExpr = [ Expression [ "," Expression ] ( "=" | ":=" ) ] "<-" Expression .
+RecvStmt = [ Expression [ "," Expression ] ( "=" | ":=" ) ] RecvExpr .
-->
<p>
-For all the send and receive expressions in the "select"
+RecvExpr must be a <a href="#Receive_operator">receive operation</a>.
+For all the cases in the "select"
statement, the channel expressions are evaluated in top-to-bottom order, along with
-any expressions that appear on the right hand side of send expressions.
+any expressions that appear on the right hand side of send statements.
A channel may be <code>nil</code>,
which is equivalent to that case not
being present in the select statement
the zero value for the channel's type without blocking.
<!-- TODO(rsc): delete next sentence, replace with
- The multi-valued <a href="#Communication_operators">receive operation</a>
+ The multi-valued <a href="#Receive_operator">receive operation</a>
returns a received value along with an indication of whether the channel is closed.
-->
After at least one such zero value has been