Go

What does this print? (select evaluation order)

Question 202HardGo 1.22 to 1.25
package main

import "fmt"

func val(s string, v int) int { fmt.Println("eval", s); return v }
func chn(s string, c chan int) chan int { fmt.Println("chan", s); return c }

func main() {
	a := make(chan int, 1)
	b := make(chan int, 1)
	b <- 0
	select {
	case chn("a", a) <- val("a", 1):
		fmt.Println("sent a")
	case <-chn("b", b):
		fmt.Println("recv b")
	}
}

Output, where the first three lines are deterministic:

chan a
eval a
chan b
sent a    // or "recv b": both are ready, chosen at random

The spec says that on entering a select, the channel operands of receives and the channel and value expressions of sends are all evaluated exactly once, in source order, whichever case ends up chosen. Only then does the select choose among the ready cases. So side effects in case expressions always happen, including for cases that aren't picked. The left-hand side of a receive assignment (case x[i()] = <-c) is evaluated only if that case is selected.

More on Channels & select

All 38 Channels & select questions