Go functions, closures and handlers
Tags: go, functions, closures, code
Published: 2022-02-28 10:02:49

---
title: Go functions, closures and handlers
published: true
date: 2021-02-06 00:00:00 UTC
tags: go, functions, closures, code
canonical_url: https://adelinasimion.dev/go/higher-order-functions-go/
---

Estimated reading time: 7 mins

While Go is not a functional language, functions are a central part of Go. They can be assigned to variables, passed as parameters and returned from other functions. This is known as _support for first class functions_ and it allows Go programmers to compose higher order functions and closures.

Understanding these mechanisms can be a powerful addition to the tool belt of any programmer, so let’s take some time to explore the behaviour of Go functions.

**Let’s get functional and elegant!**

[![Functional and Elegant Spongebob](https://media.giphy.com/media/3ohuPGgXhIzUMMimQw/giphy.gif)](https://media.giphy.com/media/3ohuPGgXhIzUMMimQw/giphy.gif)

## Basics

Functions are reusable code blocks, dedicated to performing well defined logic on inputs or _parameters_ and producing outputs or _return values_.

In Go, functions are declared using the `func` keyword. The naming convention is to use `camelCase`. Unless exported, functions are available in the same package that they are declared into.

```
func myFirstFunction() {
    fmt.Println("This is my first function!")
}

```

Functions are allowed to take zero or more parameters and return zero or more outputs. The return types must be declared in the function signature.

The function `hiBye` below says hello and goodbye using 2 different return values.

```
func hiBye(name string) (string, string) {
	return fmt.Sprintf("Hello, %s!", name),
		fmt.Sprintf("Goodbye, %s!", name)
}

func main() {
	hi, bye := hiBye("favourite reader")
	fmt.Println(hi)
	fmt.Println(bye)
}

```

`main` prints out these values to produce the output below. See this in action on the [Go playground](https://play.golang.org/p/JB5bIV_gqFr).

```
Hello, favourite reader!
Goodbye, favourite reader!

Program exited.

```

Go also supports _anonymous functions_, which can be defined inline without having to be explicitly named. In the example below, `hiBye` now only lives inside `main`, but it will have the same output as before. See for yourself in the [Go playground](https://play.golang.org/p/7KW81yKG8SX).

```
func main() {
	hiBye := func(name string) (string, string) {
		return fmt.Sprintf("Hello, %s!", name),
			fmt.Sprintf("Goodbye, %s!", name)
	}
	
	hi, bye := hiBye("favourite reader")
	
	fmt.Println(hi)
	fmt.Println(bye)
}

```

Functions can also be _deferred_ using the `defer` keyword. The deferred call’s arguments are evaluated immediately, but the function call is not executed until the surrounding function returns. The code below defers the call to `hiBye` until `main` finishes its work.

```
func main() {
	hiBye := func(name string) {
		fmt.Printf("Hello, %s!\n", name)
		fmt.Printf("Goodbye, %s!\n", name)
	}

	defer hiBye("favourite reader")

	fmt.Println("Main says hello and goodbye!")
}

```

Due to the deferred function call, `main` prints first, finishes, after which the greetings are printed. See this in action on the[Go playground](https://play.golang.org/p/tABOudtvR2c).

```
Main says hello and goodbye!
Hello, favourite reader!
Goodbye, favourite reader!

Program exited.

```

## Closures

Closures are a special case of anonymous functions, which can be a little confusing for those not used to them, so they deserve a moment to investigate.

A _closure_ is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is _bound_ to the variables.

The example below returns a closure, each referencing its own index and greet slice, thus allowing it to maintain state between invocations.

```
func greet(greetings []string) func() string {
	index := 0
	return func() string {
		greet := fmt.Sprintf("%s!", greetings[index])
		index++
		return greet	
	}
}

func main() {
	his := []string{"Hello", "Salut", "Hej"}
	byes := []string{"Goodbye", "La revedere", "Farvel"}
	hi, bye := greet(his), greet(byes)
	for i := 0; i < len(his); i++ {
		fmt.Println(
			hi(),
			bye(),
		)
	}
}

```

`main` prints out these values to produce the output below. See this in action on the[Go playground](https://play.golang.org/p/XI1N_YcFZUT).

```
Hello! Goodbye!
Salut! La revedere!
Hej! Farvel!

Program exited.

```

## Higher order functions

As seen in the basics section above, Go functions can be passed around, returned and assigned to variables. This is particularly useful for constructing a function, but not immediately invoking it.

_Higher order functions_ are those functions composed from other functions. They can either accept a function as a type or return a function. Functions can be treated as any other value type, so composing higher order functions is easy and seamless.

The `hiBye` function can now be composed of 2 separate `greet` functions and invoked only once.

```
func print(name string, hi func(string) string, bye func(string) string) {
	fmt.Printf("%s\n%s\n", hi(name), bye(name))
}

func hiBye() (func(string) string, func(string) string) {
	hi := func(name string) string {
		return fmt.Sprintf("Hello, %s!", name)
	}
	bye := func(name string) string {
		return fmt.Sprintf("Goodbye, %s!", name)
	}
	return hi, bye
}

func main() {
	hi, bye := hiBye()
	print("favourite reader", hi, bye)
}

```

`main` prints out these values to produce the same output. See this in action on the[Go playground](https://play.golang.org/p/Xank_7EAK8K).

```
Hello, favourite reader!
Goodbye, favourite reader!

Program exited.

```

## Handlers

An interesting notable mention when discussing functions is in the context of building HTTP servers using the [`net/http` package](https://golang.org/pkg/net/http/).

An HTTP _handler_ is a function that runs in response to a request made to an HTTP server.  
In Go, handlers are registered on server routes using the[`http.HandleFunc` convenience function](https://golang.org/pkg/net/http/#ServeMux.HandleFunc). It sets up the default router in the `net/http` package and takes a function as an argument.

```
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))

```

A common way to write a handler is by using the[`http.HandlerFunc` adapter](https://golang.org/pkg/net/http/#HandlerFunc) on functions with the appropriate signature. Functions serving as handlers take a `http.ResponseWriter` and a `http.Request` as arguments. The response writer is used to fill in the HTTP response.

```
type HandlerFunc func(ResponseWriter, *Request)

```

The `hiBye` function explored so far can be easily converted to a handler function to serve the greetings explored so far. Note how the `hiBye` function is passed to the `HandleFunc` as a parameter.

```
func hiBye(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintf(w, "Hello!\nGoodbye!\n")
}

func main() {
	http.HandleFunc("/hibye", hiBye)

	fmt.Println("Listening on :8090...")
	http.ListenAndServe(":8090", nil)
}

```

The full code can be seen in the[Go playground](https://play.golang.org/p/1kCaXqrIdGi), but it will need to be run locally and tested using `curl`. The output should be as below:

```
$ curl localhost:8090/hibye
Hello!
Goodbye!

```

The signature of the `HandlerFunc` is pre-defined, so what would happen if the function needed more parameters passed to it? As before, it would be great to pass a name to the greeting, as below:

```
func hiBye(w http.ResponseWriter, req *http.Request, name string) {
	fmt.Fprintf(w, "Hello, %s!\nGoodbye, %s!\n", name, name)
}

func main() {
	http.HandleFunc("/hibye", hiBye("favourite reader"))

	fmt.Println("Listening on :8090...")
	http.ListenAndServe(":8090", nil)
}

```

This throws compilation errors because `HandleFunc` is expecting a function parameter, but now the `hiBye` function has been invoked with only one parameter. Oh dear, what a pickle!

```
$ go run handlers.go
# command-line-arguments
./handlers.go:13:36: not enough arguments in call to hiBye
        have (string)
        want (http.ResponseWriter, *http.Request, string)
./handlers.go:13:36: hiBye("favourite reader") used as value 

```

While there are other solutions to this problem out in the wild, a common solution is to use a _wrapper function_ or _closure_ to pass the parameter to the `hiBye` function. In this way, the returned function still conforms to the expected signature and the greeting gets its extra parameter.

```
func hiBye(name string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s!\nGoodbye, %s!\n", name, name)
	}
}

func main() {
	http.HandleFunc("/hibye", hiBye("favourite reader"))

	fmt.Println("Listening on :8090...")
	http.ListenAndServe(":8090", nil)
}

```

The full code can be seen in the[Go playground](https://play.golang.org/p/7nTl51S9tfK), but it will need to be run locally and tested using `curl`. The output should be as below:

```
$ curl localhost:8090/hibye
Hello, favourite reader!
Goodbye, favourite reader!

```

## Parting words

That’s it for now. I’ve covered a lot of ground, but a few key points to remember are:

- Go functions can be assigned to variables, passed as parameters and returned from other functions
- Functions can be anonymous. This means they are declared inline and are not explicitly named
- Closures are anonymous functions that are bound to variables outside of their body
- Higher order functions are composed from other functions. They can either accept functions as a type or return functions
- Handlers are functions that run in response to a request made to an HTTP server

Having a good understanding of functions can help solve a wide variety of problems through composition. I hope this post gave you an insight into the wonderful world of Go functions.

**Happy Go coding!**