Clojure-like immutable data-structures and lazy lists for go.
go get github.com/mediocregopher/seq
or if you're using goat:
- loc: https://github.com/mediocregopher/seq.git
type: git
ref: v0.1.0
path: github.com/mediocregopher/seq
Check the godocs for the full API. Examples are a good place to look too.
This library constitutes an attempt at bringing immutability and laziness to go in a thread-safe way, at the cost of type-safety and code-cleanliness.
There are four available types:
List
- Single linked listSet
- Hash-tree based unordered setHashMap
- A simple key/value hash map built on top ofSet
Lazy
- Lazily evaluated sequence
All four of these implement the Seq
interface, which simply provides a way to
iterate over the structure a single time.
All operations on seq's datastructures are immutable, meaning they won't effect the original variable but instead return a new one with the change in place. Conceptually a copy is done. In reality seq uses structure sharing so only a minimal amount of copying is actually necessary.
Since all seq variables are immutable, they are also inherently thread-safe (or go-routine safe). They can be passed around and operated on by any number of go-routines with woeful abandon.
The Lazy
type is a special seq type which is conceptually similar to a
linked-list. Where it differs is that it only evalutates its elements as needed,
so if you only consume half of the "list" only half of the elements will
actually be created.
Seq provides a number of methods which operate on types implementing the Seq
interface and return a Lazy
. These include LMap
, LFilter
, and LTake
.
Since Lazy
also implements Seq
, you can chain together lazy functions like
so:
result := seq.LFilter(filterFn, seq.LMap(mapFn, l))
In the above example, no intermediate lists are created like if you had used
Map
or Filter
. Additionally, Lazy
will cache its results, so iterating
over result
multiple times would not cause the filterFn
and mapFn
functions to be called more than once on each element each. This caching is
thread-safe, so multiple go-routines can iterate over the same Lazy
safely in
all cases.
This library has its upsides and downsides, and is probably only truly useful for a minority of cases. But I had fun making it, and learned a lot, so I figured maybe someone else would to.
The license supplied in the repo applies to all code and resources provided in the repo.
Copyright Brian Picciano, 2014