Skip to content

Commit 06a9e20

Browse files
authored
Merge pull request #2017 from xushiwei/q
mini spec: Order of evaluation
2 parents 2a2f778 + 4502389 commit 06a9e20

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

doc/spec-mini.md

+37
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,43 @@ var a map[string]any = {"Monday": 1, "Sunday": 7}
836836
echo a
837837
```
838838

839+
### Order of evaluation
840+
841+
At package level, [initialization dependencies]() determine the evaluation order of individual initialization expressions in [variable declarations](). Otherwise, when evaluating the [operands]() of an expression, assignment, or [return statement](#return-statements), all function calls, method calls, [receive operations](), and [binary logical operations](#logical-operators) are evaluated in lexical left-to-right order.
842+
843+
For example, in the (function-local) assignment
844+
845+
```go
846+
y[f()], ok = g(z || h(), i()+x[j()], <-c), k()
847+
```
848+
849+
the function calls and communication happen in the order `f()`, `h()` (if z evaluates to false), `i()`, `j()`, `<-c`, `g()`, and `k()`. However, the order of those events compared to the evaluation and indexing of `x` and the evaluation of `y` and `z` is not specified, except as required lexically. For instance, `g` cannot be called before its arguments are evaluated.
850+
851+
```go
852+
a := 1
853+
f := func() int { a++; return a }
854+
x := [a, f()] // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
855+
m := {a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
856+
n := {a: f()} // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
857+
```
858+
859+
At package level, initialization dependencies override the left-to-right rule for individual initialization expressions, but not for operands within each expression:
860+
861+
```go
862+
var a, b, c = f() + v(), g(), sqr(u()) + v()
863+
864+
func f() int { return c }
865+
func g() int { return a }
866+
func sqr(x int) int { return x*x }
867+
868+
// functions u and v are independent of all other variables and functions
869+
```
870+
871+
The function calls happen in the order `u()`, `sqr()`, `v()`, `f()`, `v()`, and `g()`.
872+
873+
Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation by overriding the default associativity. In the expression `x + (y + z)` the addition `y + z` is performed before adding `x`.
874+
875+
839876
## Statements
840877

841878
Statements control execution.

0 commit comments

Comments
 (0)