Anonymous functions can be stored in variables and use surrounding values.

closure An anonymous function can close over variables from the surrounding function.

Anonymous Functions

multiplier
anonymous_functions.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var multiplier = 2
	scale := func(value int) int {
		return value * multiplier
	}
	result := scale(4)

	fmt.Println("multiplier=", multiplier)
	fmt.Println("result=", result)
}
package main

import "fmt"

func main() {
	var multiplier = 3
	scale := func(value int) int {
		return value * multiplier
	}
	result := scale(4)

	fmt.Println("multiplier=", multiplier)
	fmt.Println("result=", result)
}
package main

import "fmt"

func main() {
	var multiplier = 5
	scale := func(value int) int {
		return value * multiplier
	}
	result := scale(4)

	fmt.Println("multiplier=", multiplier)
	fmt.Println("result=", result)
}
  1. multiplier ← 2, scale ← (func(int) int)(⟨addr A⟩)

    5func main() {6  var multiplier→ 2 = 2 //@multiplier=3, 57  scale→ (func(int) int)(⟨addr A⟩) := func(value int) int {8    return value * multiplier9  }10  result := scale(4)
  2. func(value int) int

    6var multiplier = 2 //@multiplier=3, 57scale := func(value4 int) int {8  return value4 * multiplier29}
  3. result ← 8

    9  }10  result→ 8 := scale(4)1112  fmt.Println("multiplier=", multiplier2)13  fmt.Println("result=", result8)14}
    outputmultiplier= 2
    result= 8
  1. multiplier ← 3, scale ← (func(int) int)(⟨addr A⟩)

    5func main() {6  var multiplier→ 3 = 37  scale→ (func(int) int)(⟨addr A⟩) := func(value int) int {8    return value * multiplier9  }10  result := scale(4)
  2. func(value int) int

    6var multiplier = 37scale := func(value4 int) int {8  return value4 * multiplier39}
  3. result ← 12

    9  }10  result→ 12 := scale(4)1112  fmt.Println("multiplier=", multiplier3)13  fmt.Println("result=", result12)14}
    outputmultiplier= 3
    result= 12
  1. multiplier ← 5, scale ← (func(int) int)(⟨addr A⟩)

    5func main() {6  var multiplier→ 5 = 57  scale→ (func(int) int)(⟨addr A⟩) := func(value int) int {8    return value * multiplier9  }10  result := scale(4)
  2. func(value int) int

    6var multiplier = 57scale := func(value4 int) int {8  return value4 * multiplier59}
  3. result ← 20

    9  }10  result→ 20 := scale(4)1112  fmt.Println("multiplier=", multiplier5)13  fmt.Println("result=", result20)14}
    outputmultiplier= 5
    result= 20

Follow the Closure

  1. multiplier starts as 2.
  2. scale is an anonymous function stored in a variable.
  3. The function reads the surrounding multiplier.
  4. scale(4) calculates 4 * 2.
  5. The program prints multiplier= 2 and result= 8. | multiplier | call | result | | --- | --- | --- | | 2 | scale(4) | 8 | | 3 | scale(4) | 12 | | 5 | scale(4) | 20 |

Exercise: anonymous_functions.go

Reproduce multiplier= 2 and result= 8, then use the pinned multiplier variants 3 and 5 to predict result= 12 and result= 20.