Golang Closure Exercise

I always had a question, if Golang does not have the static variable, how could it gracefully handle long lifetime variables except using global variables?

Until last night, I saw this Exercise: Fibonacci closure in A tour of Go. I have to admit I am not a fan of closure, sometimes it makes easy logic complex. But it is still great for learning.

Exercise: Fibonacci closure

Let’s have some fun with functions.

Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers (0, 1, 1, 2, 3, 5, …).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	first, second := 1, 0
	return func() int {
		first, second = second, first + second
		return first
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

Usually, it is easy to choose the initial values of first and second, if the sequence starts from 1. What if the sequence starts from 0, why 1 and 0?

Let’s take a close look at the Fibonacci sequence.

$ F_0=0 \quad F_1=1 \\ and \\ F_n=F_{n-1}+F_{n-2} \\ for \quad n > 1 $

Base on the formula, it could also be extended to negative index. So it is easy to choose the initial value as $F_{-1}$ and $F_{0}$.

$ \gdef\F#1{F_{#1}} \def\arraystretch{1.5} \begin{array}{|c|c|c|c|c|c|c|c|c|c|} \hline \F{-3} & \F{-2} & \F{-1} & \F{0} & \F{1} & \F{2} & \F{3} & \F{4} & \F{5} & \F{6} \\ \hline 2 & -1 & 1 & 0 & 1 & 1 & 2 & 3 & 5 & 8 \\ \hline \end{array} $

A typical C++ implementation would not need closure, it can be implemented by static variables. It is much more straightforward, although it does not have the ability to leverage the multiple return values like first, second = second, first + second in Golang.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <iostream>

int fibonacci()
{
    static int first = 1, second = 0;
    second = first + second;
    first = second - first;
    return first;
}

int main()
{
    for (int i = 0; i < 10; i++)
    {
        std::cout << fibonacci() << std::endl;
    }
}