# Functions

Course: [Go](https://www.devtutorials.ai/learn/go) · Section: Control Flow
Source: https://www.devtutorials.ai/learn/go/control-flow/functions

> Declare and call Go functions, pass parameters, return one, many or named values, and use variadic functions, closures, higher-order functions, recursion, defer and scope.

## What Are Functions?

**Function** = a named group of steps that you can run again and again.

- You write the steps **once**.
- You **call** the function by its name whenever you need it.
- You can give it values, and it can give a value back.

You have already used functions:

- `main()` is a function you wrote.
- `fmt.Println()` is a function from the `fmt` package.

**Simple lesson:** a function is a named recipe: write it once, use it many times.

### A Real-World Example

Think of the school canteen's juice machine.

- You put in **fruit**: that is the input.
- The machine does the same steps every time: wash, cut, squeeze.
- Out comes **juice**: that is the output.
- You never need to know the steps. You just press the button.

Now the mapping:

- **The machine** = a function.
- **The fruit** = the parameters.
- **The juice** = the return value.
- **Pressing the button** = calling the function.

Functions make programs:

- **shorter**, because steps are not repeated
- **easier to read**, because each name explains a job
- **easier to fix**, because a mistake is fixed in one place

## What You Will Learn

In this lesson, you will learn:

1. How to declare and call a function.
2. How to pass one or more parameters.
3. How to return one, many, or named values.
4. Variadic functions, anonymous functions and closures.
5. How to pass functions to other functions.
6. Recursion, `defer`, and where variables can be seen (scope).

## Function Fundamentals

### Function Declaration

```go
func name(parameters) returnType {
	// steps
}
```

- `func` is the keyword that makes a function.
- The name follows the naming rules from **Variables and Constants**.
- Functions are declared **outside** `main()`, at the top level of the file.

### Calling Functions

**Call** = run a function, by writing its name and `( )`.

```go runnable title="Declare once, call twice"
package main

import "fmt"

func greet() {
	fmt.Println("Good morning, Green Valley!")
}

func main() {
	greet()
	greet()
}
```

```text
Good morning, Green Valley!
Good morning, Green Valley!
```

- Go starts at `main()`.
- Each `greet()` jumps into `greet`, runs its steps, then comes back.

**Simple lesson:** declare a function with `func`, then call it by name with `( )`.

## Parameters

**Parameter** = a variable in the function's brackets that receives a value.

**Argument** = the actual value you pass when you call it.

### Single Parameters

```go runnable title="One parameter"
package main

import "fmt"

func welcome(name string) {
	fmt.Println("Welcome,", name)
}

func main() {
	welcome("Asha")
	welcome("Ravi")
}
```

```text
Welcome, Asha
Welcome, Ravi
```

- `name string` means: this function needs one `string`.
- `"Asha"` is the argument for the first call.

### Multiple Parameters

```go runnable title="Two parameters"
package main

import "fmt"

func report(name string, marks int) {
	fmt.Println(name, "scored", marks)
}

func area(length, width int) {
	fmt.Println("Area:", length*width)
}

func main() {
	report("Meena", 88)
	area(12, 8)
}
```

```text
Meena scored 88
Area: 96
```

- Separate parameters with commas.
- `length, width int` is short for `length int, width int`.
- Arguments go in the **same order** as the parameters.

### Go Passes Copies

Go gives a function a **copy** of each argument.
Changing the copy does not change the original.

```go runnable title="The original does not change"
package main

import "fmt"

func addBonus(marks int) {
	marks = marks + 10
	fmt.Println("Inside:", marks)
}

func main() {
	marks := 70
	addBonus(marks)
	fmt.Println("Outside:", marks)
}
```

```text
Inside: 80
Outside: 70
```

- To change the original, return the new value, or use a pointer. See **Pointers**.

Go keeps functions simple:

- no default values for parameters
- no two functions with the same name (no overloading)
- every argument must be passed, in order

**Simple lesson:** parameters receive copies of the values you pass, in order.

## Return Values

**Return value** = the value a function gives back with `return`.

### Single Return Value

```go runnable title="Return one value"
package main

import "fmt"

func average(a, b, c int) float64 {
	return float64(a+b+c) / 3
}

func main() {
	avg := average(80, 90, 76)
	fmt.Println(avg)
}
```

```text
82
```

- `float64` after the brackets is the **return type**.
- `return` sends the value back and ends the function at once.

### Multiple Return Values

Go functions can return **more than one** value.

```go runnable title="Return two values"
package main

import "fmt"

func divide(total, people int) (int, int) {
	return total / people, total % people
}

func main() {
	each, left := divide(17, 5)
	fmt.Println("Each gets", each, "laddoos,", left, "left over")
}
```

```text
Each gets 3 laddoos, 2 left over
```

- List the types in brackets: `(int, int)`.
- Receive them with two names: `each, left := ...`.
- Go uses this for errors: `value, err := strconv.Atoi("42")`.

### Named Return Values

**Named return values** = return values that have names, like variables.

```go runnable title="Named return values"
package main

import "fmt"

func minMax(a, b, c int) (smallest, biggest int) {
	smallest, biggest = a, a
	for _, n := range []int{b, c} {
		if n < smallest {
			smallest = n
		}
		if n > biggest {
			biggest = n
		}
	}
	return
}

func main() {
	low, high := minMax(72, 95, 64)
	fmt.Println(low, high)
}
```

```text
64 95
```

- `smallest` and `biggest` start at their zero values.
- A bare `return` sends back their current values.
- Good for short functions. In long ones, `return smallest, biggest` is clearer.

**Simple lesson:** `return` gives values back, and Go functions can return several at once.

## Variadic Functions

**Variadic function** = a function that takes **any number** of arguments of one type.

Write `...` before the type of the last parameter.

```go runnable title="Add any number of marks"
package main

import "fmt"

func total(marks ...int) int {
	sum := 0
	for _, m := range marks {
		sum += m
	}
	return sum
}

func main() {
	fmt.Println(total())
	fmt.Println(total(90, 85))
	fmt.Println(total(70, 80, 90, 100))

	list := []int{10, 20, 30}
	fmt.Println(total(list...))
}
```

```text
0
175
340
60
```

- Inside the function, `marks` is a slice: `[]int`.
- `list...` spreads a slice into separate arguments.
- `fmt.Println` itself is variadic. That is why it takes any number of values.

**Simple lesson:** `...type` lets a function take as many values as you like.

## Anonymous Functions and Closures

### Function Literals

**Anonymous function** = a function with no name. It is also called a **function literal**.

```go runnable title="Functions without names"
package main

import "fmt"

func main() {
	double := func(n int) int {
		return n * 2
	}
	fmt.Println(double(21))

	func(msg string) {
		fmt.Println(msg)
	}("Called right away")
}
```

```text
42
Called right away
```

- You can store a function in a variable, like `double`.
- You can also call it at once by adding `( )` after the `}`.

### Closures and Lexical Scope

**Closure** = a function that remembers the variables around it, even after the outer function has finished.

**Lexical scope** = a function can see the variables of the code that surrounds it.

- `tokenMaker` has finished, but `next` is not lost.
- The returned function **closes over** `next`. That is why it is called a closure.
- Each call to `tokenMaker()` makes a new, separate counter.

**Simple lesson:** a function literal is a function without a name, and a closure is one that remembers its surroundings.

## Higher-Order Functions

**Higher-order function** = a function that takes a function, or returns one.

### Passing Functions

The type of a function is written like `func(int) int`.

```go runnable title="Pass a rule into a function"
package main

import "fmt"

func applyToAll(marks []int, rule func(int) int) {
	for _, m := range marks {
		fmt.Print(rule(m), " ")
	}
	fmt.Println()
}

func main() {
	marks := []int{40, 65, 90}
	addGrace := func(m int) int { return m + 5 }
	outOfFifty := func(m int) int { return m / 2 }

	applyToAll(marks, addGrace)
	applyToAll(marks, outOfFifty)
}
```

```text
45 70 95 
20 32 45 
```

- `applyToAll` does not know the rule. It just calls it.
- You choose the rule when you call it.

### Returning Functions

```go runnable title="A function that makes functions"
package main

import "fmt"

func multiplier(k int) func(int) int {
	return func(x int) int {
		return x * k
	}
}

func main() {
	double := multiplier(2)
	triple := multiplier(3)
	fmt.Println(double(7), triple(7))
}
```

```text
14 21
```

- `multiplier(2)` builds a new function that remembers `k = 2`.
- This is a closure too.

**Simple lesson:** functions are values: you can pass them in and return them.

## Recursion

**Recursion** = a function that calls itself.

### Base Case

Every recursive function needs two parts:

- **Base case** = the simple case that stops the calls.
- **Recursive case** = the function calls itself with a smaller problem.

Without a base case, the calls never stop.

### Recursive Functions

**Factorial** of 4 = 4 × 3 × 2 × 1 = 24.

Press **Play** and watch the calls stack up, then come back down.

```go runnable title="factorial with recursion"
package main

import "fmt"

func factorial(n int) int {
	if n <= 1 {
		return 1
	}
	return n * factorial(n-1)
}

func main() {
	fmt.Println(factorial(4))
	fmt.Println(factorial(6))
}
```

```text
24
720
```

- **Call stack** = the pile of function calls waiting for an answer.
- Each call waits on the stack until the call above it returns.
- Too many calls (no base case) fill the stack, and the program crashes.

**Simple lesson:** a recursive function calls itself on a smaller problem, and the base case stops it.

## Deferred Calls

### defer

**defer** = run this call later, just before the function ends.

- It is used for clean-up, like closing a file. See **File Handling**.
- The deferred call runs even if the function ends early.

```go runnable title="defer runs at the end"
package main

import "fmt"

func main() {
	fmt.Println("Open the library")
	defer fmt.Println("Lock the library")
	fmt.Println("Issue books")
	fmt.Println("Collect returns")
}
```

```text
Open the library
Issue books
Collect returns
Lock the library
```

### Multiple defer Statements

Many deferred calls run in **reverse** order: last in, first out.

Think of a stack of plates. The last plate you put on top is the first one you take off.

- The arguments of a deferred call are worked out **when the `defer` line runs**, not at the end.

**Simple lesson:** `defer` saves a call for the end of the function, and many defers run in reverse order.

## Function Scope

**Scope** = the part of the code where a name can be used.

### Local Scope

**Local variable** = a variable made inside a function or block. It exists only there.

### Package Scope

**Package-level variable** = a variable made outside every function. All functions in the package can use it.

```go runnable title="Local and package scope"
package main

import "fmt"

var school = "Green Valley School"

func printHeader() {
	title := "Annual Report"
	fmt.Println(school, "-", title)
}

func main() {
	printHeader()
	count := 3
	if count > 0 {
		message := "Students present"
		fmt.Println(message, count)
	}
	fmt.Println(school)
}
```

```text
Green Valley School - Annual Report
Students present 3
Green Valley School
```

- `school` is package scope: both functions use it.
- `title` lives only inside `printHeader`.
- `message` lives only inside the `if` block.

### Shadowing

**Shadowing** = an inner variable with the same name hides the outer one.

```go runnable title="An inner variable hides the outer one"
package main

import "fmt"

var level = "school"

func main() {
	level := "class"
	fmt.Println(level)
	{
		level := "bench"
		fmt.Println(level)
	}
	fmt.Println(level)
}
```

```text
class
bench
class
```

- Each `:=` makes a **new** variable in a smaller scope.
- Shadowing is legal, but it confuses readers. Use different names.

**Easy way to remember**

- Made inside `{ }` = lives inside those `{ }`.
- Made outside every function = the whole package can use it.
- Keep variables in the smallest scope that works.

**Simple lesson:** a variable lives only inside the braces where it was made.

## TL;DR

1. **Function** = `func name(params) returnType { }`. Call it with `name(args)`.
2. **Parameters** = inputs. Go passes **copies**.
3. **Return values** = `return x`. Go can return many: `(int, error)`.
   - **Named returns** = `(total int)`, then a bare `return`.
4. **Variadic** = `func sum(nums ...int)`. Spread a slice with `list...`.
5. **Anonymous function** = `func(x int) int { ... }`.
   - **Closure** = a function that remembers outer variables.
6. **Higher-order** = takes or returns a function.
7. **Recursion** = a function calls itself. Needs a **base case**.
8. **defer** = run at the end, in reverse order.
9. **Scope** = local (inside `{ }`) or package (outside functions).

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| A function inside `main()` with `func name()` | Named functions can go anywhere | Named functions go at the top level | A syntax error. Use a function literal inside. |
| Forgetting `return` in a function with a return type | Go returns the last value | Every path must `return` | `missing return` |
| Changing a parameter to change the caller's variable | Parameters are the same box | Parameters are copies | The original does not change. |
| `a, b := f()` when `f` returns one value | You can take as many as you like | Take exactly as many as it returns | `assignment mismatch` |
| Recursion with no base case | It stops by itself | A base case must stop it | The stack overflows and the program crashes. |
| Expecting `defer` to run in written order | First defer runs first | Last defer runs first | Clean-up happens in the wrong order. |
| Using a local variable in another function | Variables are shared | Locals live inside their braces | `undefined: title` |

## Check Yourself

## Exercises

## What to Remember

- A function is a named recipe: `func name(params) returnType { }`.
- Parameters get **copies**. Go functions can return many values.
- `...type` makes a function take any number of values.
- Functions are values: you can store them, pass them and return them.
- A closure remembers the variables around it.
- Recursion needs a base case. `defer` runs at the end, in reverse order.
- A variable lives inside the braces where it was made.

Next: **Packages and Modules**. You will learn how Go organises code into packages, and how modules manage a whole project.
