Introduction #
go-optics is a go library that provides a solution for updating immutable data structures in go.
Immutability in Go. #
There are various current approaches to immutability in Go.
- use unexported fields with a read only interface
- special read-only collections
These partially solve the problems with handling immutable data in Go but currently fall short. Take the following example data model.
type Comment struct {
title string
content string
}
type BlogPost struct {
content string
comments []Comment
}
This represents a simple blog post with comments and ratings.
Consider the code needed to update the content of a comment while retaining immutability.
| |
Now consider we need to implement or generate the same boilerplate for the other fields of Comment and also perform the same exercise for ratings.
That’s a lot of boilerplate and the only way to reference a comment was by slice index. Optics provide a powerful solution to this problem of handling nested immutable data structures.
Using optics the above code would become
| |
There is a lot to unpack here. The single statement in the function can be broken down into the following components.
MustSet–> This is an action that sets the focused element to the given valueO.BlogPost().Comment().Nth(commentIndex),Content()-> This is the optic. It describes a path from a source (BlogPost) to a focus (theContentstring of a comment)newContent-> this is the new value that the set action will apply to the optic.blogPost–> this is the source that will be immutably updated
In this example the MustSet action returns a new BlogPost with only the focused comment content updated.
Optics can also be read from. e.g. to read the same content from the BlogPost the following code can be used.
| |
This doesn’t seem all that useful as the user could have easily written blogPost.comments[commentIndex].content But consider again that the comments and content fields are unexported. The optic methods are exported and can be used from outside the defining package while still retaining immutability when updating.
The O.BlogPost() is a convenience function generated by the go-optics makelens tool.
Summary #
The go optics library provides functionality to focus on deeply nested elements within an immutable data structure. When performing an update to an immutable data structure the optics library takes care of all the boilerplate required to build up the immutable data structure surrounding the updated values.