First-Class Functions in Go

- Go supports first class functions, higher-order functions, user-defined function types, function literals, closures, and multiple return values.

  This rich feature set supports a functional programming style in a strongly typed language.

  In this codewalk we will look at a simple program that simulates a dice game called Pig and evaluates basic strategies.
- Pig is a two-player game played with a 6-sided die. Each turn, you may roll or stay.
  - If you roll a 1, you lose all points for your turn and play passes to your opponent. Any other roll adds its value to your turn score.
  - If you stay, your turn score is added to your total score, and play passes to your opponent.

  The first person to reach 100 total points wins.

  The `score` type stores the scores of the current and opposing players, in addition to the points accumulated during the current turn.
- In Go, functions can be passed around just like any other value. A function's type signature describes the types of its arguments and return values.

  The `action` type is a function that takes a `score` and returns the resulting `score` and whether the current turn is over.

  If the turn is over, the `player` and `opponent` fields in the resulting `score` should be swapped, as it is now the other player's turn.
- Go functions can return multiple values.

  The functions `roll` and `stay` each return a pair of values. They also match the `action` type signature. These `action` functions define the rules of Pig.
- A function can use other functions as arguments and return values.

  A `strategy` is a function that takes a `score` as input and returns an `action` to perform.
  (Remember, an `action` is itself a function.)
- Anonymous functions can be declared in Go, as in this example. Function literals are closures: they inherit the scope of the function in which they are declared.

  One basic strategy in Pig is to continue rolling until you have accumulated at least k points in a turn, and then stay. The argument `k` is enclosed by this function literal, which matches the `strategy` type signature.
- We simulate a game of Pig by calling an `action` to update the `score` until one player reaches 100 points. Each `action` is selected by calling the `strategy` function associated with the current player.
- The `roundRobin` function simulates a tournament and tallies wins. Each strategy plays each other strategy `gamesPerSeries` times.
- Variadic functions like `ratioString` take a variable number of arguments. These arguments are available as a slice inside the function.
- The `main` function defines 100 basic strategies, simulates a round robin tournament, and then prints the win/loss record of each strategy.

  Among these strategies, staying at 25 is best, but the optimal strategy for Pig is much more complex.