HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoMinor

Fibonacci implementation in Go

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationfibonaccistackoverflow

Problem

At the end of the Day 1 Go Course slides (pdf) there is an exercise stated as follows (NOTE: the course in the linked presentation is considered obsolete. If you are looking to learn Go the suggested route is first via http://tour.golang.org):


You all know what the Fibonacci series is. Write a package to implement it. There should be a function to get the next value. (You don't have structs yet; can you find a way to save state without globals?) But instead of addition, make the operation settable by a function provided by the user. Integers? Floats? Strings? Up to you.

How does the following solution rate with respect to its 'Go'-iness?

package fib

type BinOp func (uint64, uint64) uint64

func fib_intern(a, b uint64, op BinOp) uint64 {
    Fib = func(opnew BinOp) uint64 {
        return fib_intern(b, op(a,b), opnew)
    }
    return a
}

var Fib = func(op BinOp) uint64 {
    return fib_intern(0,1,op)
}


Which can then be called like:

package main

import (
    "./fib"
    "fmt"
)

func add(a, b uint64) uint64 {
    return a+b
}

func main() {
    for i := 0; i < 20; i++ {
        fmt.Println(fib.Fib(add))
    }
}

Solution

The link is dead and the code doesn't compile, but there is still an obvious issue to critique: Part of the challenge was to not save state with "global variables." In Go, package variables of the package main are typically considered "global variables". However, only a single instance of any package ever exists at run time, so package variables of all packages are essentially global variables as well. The code here uses a package variable fib.Fib, thus the code is failing the exercise from the start, working or not.

Edit: Thank you Anthony for tracking down the archived course and updating the question. It helps to have the full context. It also helps to have code working with a current version of Go, which is pretty easy:

package fib

type BinOp func(uint64, uint64) uint64

var Fib func(op BinOp) uint64

func init() {
    Fib = func(op BinOp) uint64 {
        return fib_intern(0, 1, op)
    }
}

func fib_intern(a, b uint64, op BinOp) uint64 {
    Fib = func(opnew BinOp) uint64 {
        return fib_intern(b, op(a, b), opnew)
    }
    return a
}


Go now has stricter checking of static dependencies and reports "initialization loop" with the old code. My update of your code works by moving the initial assignment of Fib to an init function, which runs at program startup.

I'll abandon this answer now and add another answer where I try to stick to your request for a review of the 'Go'-iness.

Code Snippets

package fib

type BinOp func(uint64, uint64) uint64

var Fib func(op BinOp) uint64

func init() {
    Fib = func(op BinOp) uint64 {
        return fib_intern(0, 1, op)
    }
}

func fib_intern(a, b uint64, op BinOp) uint64 {
    Fib = func(opnew BinOp) uint64 {
        return fib_intern(b, op(a, b), opnew)
    }
    return a
}

Context

StackExchange Code Review Q#4860, answer score: 6

Revisions (0)

No revisions yet.