- 
      
 - 
        
Save weppos/7843653 to your computer and use it in GitHub Desktop.  
| package main | |
| import "fmt" | |
| // fibonacci is a function that returns | |
| // a function that returns an int. | |
| func fibonacci() func() int { | |
| f2, f1 := 0, 1 | |
| return func() int { | |
| f := f2 | |
| f2, f1 = f1, f+f1 | |
| return f | |
| } | |
| } | |
| func main() { | |
| f := fibonacci() | |
| for i := 0; i < 10; i++ { | |
| fmt.Println(f()) | |
| } | |
| } | 
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func(int) int {
	first := 0
	second := 1
	return func(i int) int {
		if i == 0 || i == 1 {
			return i
		}
		sum := first + second
		first = second
		second = sum
		return sum
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f(i))
	}
}My version:
func fibonacci() func() int { a, b := 1, 0 return func() int { a, b = b, a+b return a } }
it's not your solution, this solution belongs to @stvr in 2012
func fibonacci() func() int {
	previous := 0
	last := 0
	index := 0
	
	return func() int {
		var result int
		if index == 1 {
			result = 1
		} else {
			result = last + previous	
		}
		
		previous = last;
		last = result;
		index++
		
		return int(result)
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}This is what I came up, before searching for other's solutions. Mine doesn't modify main(), which I believe was part of the spirit of the exercise. Otherwise, very close to banothurameshnaik's solution.
In any case, I find this more readable than the first example as someone new to Go (but with 30+ years programming experience). Is the bunching of multiple assignments on a line (e.g. a, b := 1, 0) really considered "best practice"? Seems like it's being clever at the expense of readability. Probably biased by my experience with other languages. Maybe my opinion will change over time. Other than slightly less typing and fewer lines, what else would be the advantage of using the shorter notation?
Thanks in advance for any opinions.
This starts with zero and does not modifies main()
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		result := a // Store the result value before translations
		c := a + b // Fibonacci
		a = b // Translation
		b = c // Translation
		return result
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a: = 0
    b: = 1
    sum: = a + b
    return func() int {
        if a == 0 {
            a = b
            return 0
        }
        a = b
        b = sum
        sum = a + b
        return a
    }
}
func main() {
    f: = fibonacci()
    for i: = 0;i < 10;i++{
        fmt.Println(f())
    }
}```
    
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 1, 0
	return func() int {
		a, b = b, a+b // two assignment happens parallely, but if you enforce it sequentially, it won't work
		return a
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    use slice
package main
import "fmt"
func fibonacci() func() int {
	var i []int
	return func() int {
		if len(i) == 0 {
			i = append(i, 0)
		} else if len(i) == 1 {
			i = append(i, 1)
		} else {
			i = append(i, i[len(i)-2]+i[len(i)-1])
		}
		return i[len(i)-1]
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    Using defer
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	cum1 := 0
	cum2 := 1
	return func() int {
		defer func() { cum1, cum2 = cum2, cum1+cum2 }()
		return cum1
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}I like your answer! I can do fib numbers but a bit tricky with this problem with closures. Thank you for your answer!
one letter variables is evil (except loop var)
traditional
func fibonacci() func() int {
	current := 0
	next := 1
	return func() int {
		current, next = next, current+next
		return current
	}
}
with defer
func fibonacci() func() int {
	current := 1
	next := 1
	return func() int {
		defer func() {
			current, next = next, current+next
		}()
		return current
	}
}
    package main
import "fmt"
func fibonacci() func() []int {
	arr := make([]int,0)
	return func() []int {
		switch len(arr){
			case 0:
				arr = append(arr,0)
			case 1:
				arr = append(arr,1)
			default:
				arr = append(arr,arr[len(arr)-1]+ arr[len(arr)-2])
			
		}
		return arr
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}Here is my solution -
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	x, y := 0, 1
	return func() int{
		x++
		y++
		return (x-1)+(y-2)
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    Not as elegant but doing the job:
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	i := -1
	f1 := 0
	f2 := 1
	return func() int {
		switch i+=1; i {
		case 0:
			return 0	
		case 1:
			return 1
		default:
			f := f1 + f2
			f1 = f2
			f2 = f
			return f
		}
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    We can omit the variable f with
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	f1, f2 := 0, 1
	return func() int {
		f1, f2 = f2, f1+f2
		return f1
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    similar to other solutions using if statements
Hope it helps someone out there
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func(int) int {
	
	prev2 := 0
	prev1 := 1
	
	return func(x int ) int{
		
		sum:=0
		
		//SKIPPING FIRST 2 ITTERATION
		if x == 0{
			return 0
		}else if x == 1{
			return 1
		}else{
			//Staring at 2 value should still be 1
			sum = prev1 + prev2
		}
	
		//THEN MAKE PREVIOUS VALUES CURRENT FOR NEXT ITTERATION
		prev2 = prev1 
		prev1 = sum 
		
		
		//RETURN THE RESULT
		return fib
	}
	
}
func main() {
	//Assigning a function fibonacci
	f := fibonacci()
	
	//now looping through and passing i each time
	for i := 0; i < 10; i++ {
		fmt.Println(i,"->",f(i))
	}
}
    package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	f1, f2 := 0, 1
	
	return func() int {
		// f is previous fibonacci number
		// f() closure actually returns
		// previous fibonacci number
		f := f1
		f1, f2 = f2, f1+f2
		
		return f
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}With defer
func fibonacci() func() int {
	var v0, v1 int = 0,1
	advance := func () {
		v0, v1 = v1, v0+v1
	}
	return func() int {
		defer advance()
		return v0
	}
}
    package main
import "fmt"
func fibonacci() func() uint64 {
	
	a := uint64(0)
	b := uint64(0)
	c := uint64(a + b)
	return func() uint64 {
		if c-a > c-b {
			c = c + (c - a)
			a = c - b
			return c
		} else if c-a < c-b {
			c = c + (c - b)
			b = c - a
			return c
		} else if c == c {
			a += 0
			b += 1
			c += 1
			return c
		}
		return c
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 1000; i++ {
		fmt.Println(f())
	}
}
    package main
import "fmt"
func fibonacci() func() int {
	f := [10]int{0, 1}
	i := 0
	return func() int {
		last := i
		i++
		if last == 0 || last == 1 {
			return f[last]
		}
		f[last] = f[last-1] + f[last-2]
		return f[last]
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}package main
import "fmt"
func fibonacci() func() int {
	fib, temp, next := 0, 0, 1
	
	return func() int {
		fib = temp
		temp = next
		next = fib + temp
		return fib
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	num := 0
	nextNum := 1
	advance := func () {
		temp := nextNum
		nextNum = num + nextNum
		num = temp
	}
	return func () int {
		defer advance()
		return num
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
f1 := 0
f2 := 1
reFunc := func() int {
f := f1
f1 = f2
f2 = f + f1
return f
}
return reFunc
}
func main() {
f := fibonacci()
for i := 0; i < 100; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
func fibonacci() func() int {
	a, b := 1, 0
	return func() int {
		a, b = b, a + b
		return a
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}hehe basically we all disagree about variables names 😄
package main
import "fmt"
// fibonacci is a fucntion that returns
// a function that returns an int.
func fibonacci() func() int {
	current, next := 0, 1
	return func() int {
		fib := current
		current, next = next, current+next
		return fib
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}P.S.: The solution with the defer statement is pure gold 🥇
P.S.: The solution with the
deferstatement is pure gold 🥇
Could you please elaborate on what's so special about using defer here? I do not see any improvement over not using it.
Could you please elaborate on what's so special about using defer here? I do not see any improvement over not using it.
two things:
- When I was solving the exercise, using 
defernever crossed my mind, so when I saw that solution it was anahá moment🤯 - I saw it as a readability improvement for sure, the combination between 
Function closures(link) and thedeferstatement, imho it's way simpler to read: 
func fibonacci() func() int {
	current, next := 0, 1
	return func() int {
		defer func() {
			current, next = next, current+next
		}()
		return current
	}
}@pabloxio, I think I understand now how it works (the trick is that values will be updated after current is returned), but I do not really see any improvement between the defer approach and something like this:
func fibonacci() func() int {
	curr, next := 1, 0
	return func() int {
		curr, next = next, curr + next
		return curr
	}
}Am I missing something?
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		result := a
		a, b = b, a + b
		return result
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
    
My version: