Go handles first-class functions and closures in a pretty typical / standard way. For some good background on closures in general, see the Wikipedia article. In this case, calling adder itself:
- Creates the
int object named sum with value 0.
- Returns a closure: a function-like thingy1 that, when called, has access to the variable
sum.
The particular function-like thingy that adder returns, which its caller captures in an ordinary variable, is a function that takes one argument. You then call it, passing the one argument. There's nothing special about this argument-passing: it works the same way as it would anywhere else. Inside the function-like thingy, using the variable x gets you the value that the caller passed. Using the name sum gets you the captured int object, whatever its value is. Returning from the function leaves the captured int still captured, so a later call to the same function-like thingy sees the updated int in sum.
By calling adder twice, you get two slightly-different function-like thingies: each one has its own private sum. Both of these private sums are initially zero. Calling the function-like thingy whose value you've saved in pos gets you the function that uses one of them. Calling the slightly-different function-like thingy whose value you've saved in neg gets you the function that uses the other one.
1There's no real difference between this "function-like thingy" and an actual function except that this particular function-like thingy doesn't have a name by which you can invoke it. That's more or less what it means to have first-class functions.
If you're stuck on readability issues...
The original form of this is:
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
Let's rewrite this with a few type names and other syntactic changes that leave the core of the code the same. First, let's make a name that means func(int) int:
type adderClosure func(int) int
Then we can use that to rewrite adders first line:
func adder() adderClosure {
...
}
Now let's make a local variable inside adder to hold the function we're going to return. To be explicit and redundant, we can use this type again:
var ret adderClosure // not good style: just for illustration
Let's now assign that variable to our closure by doing this:
sum := 0
ret = func(x int) int {
sum += x
return sum
}
and then we can return ret to return the closure. Here's the complete code on the Go Playground.