First class functions

Monday, Nov 27, 2017
go programming

What are first class functions?

If you stumble upon first class functions what usually mean is, that functions are part of the type system of your language. So you can assign a method to a function. As an example:

package main

import "fmt"

var a func(a int) int

func main() {
        a = func (a int ) int {
                return a * a
        }

        fmt.Println(a(2)) // prints 4
}

RUN

At first this does not seem like a big deal but you can use functions as parameters to other functions, thereby injecting different behavior into the function using that function:

package main

import "fmt"

func main() {
        // prints 4
        fmt.Println(doSomething(func(a int) int {
                return a
        }))

        // prints 8
        fmt.Println(doSomething(func(a int) int {
                return a * a
        }))
}

func doSomething(a func (a int) int) int {
        return a(2) * 2
}

RUN

Now suppose a function that returns a function of a specific signature based on input parameters. That function then is passed to another function that performs the actual work you would expect:

package main

import "fmt"

type (
        Operator int
)

func MultiplyByTwo(a int) int {
        return a * 2
}

func SquareFunc(a int) int {
        return a * a
}

const (
        Multiply = 1 + iota
        Square
)

func getFunction(op Operator) func (a int) int {
        switch op {
        case Multiply:
                return MultiplyByTwo
        case Square:
                return SquareFunc
        default:
                return func (a int) int {
                        return a
                }
        }
}

func do(a func (a int) int, value int) int {
        return a(value)
}

func main() {
        fmt.Println(do(getFunction(Multiply), 2)) // prints 4
        fmt.Println(do(getFunction(Square), 2)) // prints 4
        fmt.Println(do(getFunction(Multiply), 3)) // prints 6
        fmt.Println(do(getFunction(Square), 3)) // prints 9
}

RUN

Another word you may hear in this are anonymous functions. You have them seen in example 2. It is a function not bound to an identifier.

Some more research and you will find references to lambda calculus. See Wikipedia for a formal introduction. Specifically in this context the idea of functions that operate on functions is one of the main ideas in lambda calculus.

Dave Cheney gave a good talk @dotGo 2016 on this topic, it is definitly woth a look: