# More Functions

## Function Values

Functions are values too. They can be passed around just like other values. Function values may be used as function arguments and return values.

### Example

```go
package main

import (
	"fmt"
	"math"
)

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(5, 12))
	fmt.Println(compute(hypot))
	fmt.Println(compute(math.Pow))	
}
```

```bash
13
5
81
```

## Function Closures

Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.

### Example 1 (No Parameter)

```go
package main

import "fmt"

func increment() func() int {
    var x int
    return func() int {
        x++
        return x
    }
}

func main() {
    a := increment()
    b := increment()
    
    fmt.Println("a: ", a())
    fmt.Println("a: ", a())
    fmt.Println("a: ", a())
    
    fmt.Println("b: ", b())
}
```

```bash
a:  1
a:  2
a:  3
b:  1
```

{% hint style="info" %}
Notice here `a` and ~~`b`~~ have their own closure and each is bound to its own `x` variable
{% endhint %}

### Example 2 (With Parameter)

```go
package main

import "fmt"

func adder() func(int) int {	// two return types: a func and an int
	sum := 0
	return func(x int) int {		// return an anonymous function
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-1*i),
		)
	}
}
```

```bash
0 0
1 -1
3 -3
6 -6
10 -10
15 -15
21 -21
28 -28
36 -36
45 -45
```

{% hint style="info" %}
&#x20;The `adder` function returns a closure. Each closure is bound to its own `sum` variable.
{% endhint %}

### More About Closure

{% embed url="<https://dev.to/spindriftboi/function-literals-and-closure-in-go-2hgn#:~:text=A%20Function%20Literal%20is%20a,literal%20and%20the%20surrounding%20function.&text=when%20this%20function%20is%20invoked,I%20am%20a%20function%20literal>!" %}
Great article!
{% endembed %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.yushunchen.com/golang-notes/official-tutorial-notes/more-types/more-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
