Closures

A closurearrow-up-right is a function that references variables from outside its own function body. The function may access and assign to the referenced variables.

In this example, the concatter() function returns a function that has reference to an enclosed doc value. Each successive call to harryPotterAggregator mutates that same doc variable.

func concatter() func(string) string {
	doc := ""
	return func(word string) string {
		doc += word + " "
		return doc
	}
}

func main() {
	harryPotterAggregator := concatter()
	harryPotterAggregator("Mr.")
	harryPotterAggregator("and")
	harryPotterAggregator("Mrs.")
	harryPotterAggregator("Dursley")
	harryPotterAggregator("of")
	harryPotterAggregator("number")
	harryPotterAggregator("four,")
	harryPotterAggregator("Privet")

	fmt.Println(harryPotterAggregator("Drive"))
	// Mr. and Mrs. Dursley of number four, Privet Drive
}

Assignment

Keeping track of how many texts we send is mission-critical at Textio. Complete the adder() enclosing functionarrow-up-right It should return a function that adds its input (an int) to an enclosed sum value, then return the new sum. In other words, it keeps a running total of the sum variable within a closure.

🧩 The function definition

means:

"adder is a function that returns another function β€” and that inner function takes an int and returns an int."

So:

  • The outer function: adder()

  • The inner function: func(int) int


1

1️⃣ Outer function

When you call adder(), it:

  • Creates a local variable sum (set to 0)

  • Returns a new function (the anonymous one inside)

  • That inner function has access to the variable sum β€” even after adder() finishes!

This is called a closure β€” it β€œcloses over” the sum variable and keeps it alive.

2

2️⃣ Inner function

The inner function takes a number, adds it to sum, and returns the total.

Key point: Each time you call this returned function, it keeps using the same sum variable from when it was created.


βš™οΈ Using it in action

Let’s add a main():

Output:

Here’s what happens:

  1. adder() creates its own sum = 0 and returns a function.

  2. When you call add(3), that inner function updates the same sum to 3.

  3. When you call add(5), it adds to that same sum (now 8).

  4. When you call add(10), it adds again (now 18).

The outer variable sum persists between calls because of the closure.


🧠 Visualization

Every time you call adder(), you get a new copy of that closure and its own sum.


βœ… TL;DR

Part
Meaning

func adder()

A function named adder

func(int) int

The type of function it returns (takes an int, returns an int)

Inner func(number int) int

The actual function being returned

sum

A variable captured by the closure, preserved across calls


βš™οΈ Bonus example

You can even create multiple independent adders:

Each has its own sum β€” they don’t interfere with each other.


So the magic is:

func adder() func(int) int means β€œa function that returns a function,” and that returned function remembers the variable from the outer one β€” that’s a closure.


🧠 What’s really happening

When you call:

you’re doing two things:

  1. Calling the function adder()

  2. Storing whatever adder() returns into a variable named add.


βš™οΈ What does adder() return?

It returns another function β€” specifically, this one:

That inner function has no name β€” it’s anonymous β€” but you’re saving it into the variable add.

So add now points to that returned function.


βœ… So when you later write:

you’re just calling the function that add is storing.

It’s exactly the same idea as:

You gave the anonymous function a name by assigning it to a variable β€” here f, in your example add.


πŸ’‘ Analogy

Think of adder() like a machine that builds a custom calculator for you.

Now whenever you use it:

…it’s using that same calculator, which remembers its total (sum).

If you called:

You’d get a second calculator with its own memory.


πŸ” Summary

Concept
Explanation

Anonymous function

A function with no name (func(number int) int { ... })

add := adder()

Calls adder() and stores the returned (anonymous) function in add

add(3)

Calls the function stored in add

Why it works

Because functions in Go are values β€” you can assign them to variables and call them later


So yes β€” you gave the returned anonymous function the name add yourself when you did this:

You could have called it literally anything:

It would behave the same way.