Skip to content

Commit

Permalink
Merge pull request #23 from laher/master
Browse files Browse the repository at this point in the history
Adds generics
  • Loading branch information
benbjohnson authored Oct 4, 2022
2 parents 1cc5739 + 33d5f13 commit d4a6ab5
Show file tree
Hide file tree
Showing 6 changed files with 720 additions and 1,094 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.15.x
go-version: 1.18.x
- name: Checkout code
uses: actions/checkout@v2
- name: Short test
Expand All @@ -22,7 +22,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.15.x
go-version: 1.18.x
- name: Checkout code
uses: actions/checkout@v2
- name: Test
Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Immutable ![release](https://img.shields.io/github/release/benbjohnson/immutable.svg) ![test](https://github.com/benbjohnson/immutable/workflows/test/badge.svg) ![coverage](https://img.shields.io/codecov/c/github/benbjohnson/immutable/master.svg) ![license](https://img.shields.io/github/license/benbjohnson/immutable.svg)
=========

This repository contains immutable collection types for Go. It includes
This repository contains *generic* immutable collection types for Go. It includes
`List`, `Map`, and `SortedMap` implementations. Immutable collections can
provide efficient, lock free sharing of data by requiring that edits to the
collections return new collections.
Expand Down Expand Up @@ -34,7 +34,7 @@ prepending is as efficient as appending.

```go
// Create a list with 3 elements.
l := immutable.NewList()
l := immutable.NewList[string]()
l = l.Append("foo")
l = l.Append("bar")
l = l.Prepend("baz")
Expand All @@ -46,7 +46,7 @@ fmt.Println(l.Get(2)) // "bar"
```

Note that each change to the list results in a new list being created. These
lists are all snapshots at that point in time and cannot be changed so they
lists are all snapshots at that point in time and cannot be changed so they
are safe to share between multiple goroutines.

### Updating list elements
Expand All @@ -57,7 +57,7 @@ new list to a new variable. You can see that our old `l` variable retains a
snapshot of the original value.

```go
l := immutable.NewList()
l := immutable.NewList[string]()
l = l.Append("foo")
l = l.Append("bar")
newList := l.Set(2, "baz")
Expand Down Expand Up @@ -95,7 +95,7 @@ Below is an example of iterating over all elements of our list from above:
```go
itr := l.Iterator()
for !itr.Done() {
index, value := itr.Next()
index, value, _ := itr.Next()
fmt.Printf("Index %d equals %v\n", index, value)
}

Expand All @@ -115,7 +115,7 @@ a list in-place until you are ready to use it. This can improve bulk list
building by 10x or more.

```go
b := immutable.NewListBuilder()
b := immutable.NewListBuilder[string]()
b.Append("foo")
b.Append("bar")
b.Set(2, "baz")
Expand Down Expand Up @@ -151,7 +151,7 @@ the value as well as a flag indicating if the key existed. The flag is useful
to check if a `nil` value was set for a key versus a key did not exist.

```go
m := immutable.NewMap(nil)
m := immutable.NewMap[string,int](nil)
m = m.Set("jane", 100)
m = m.Set("susy", 200)
m = m.Set("jane", 300) // overwrite
Expand All @@ -175,7 +175,7 @@ Keys may be removed from the map by using the `Delete()` method. If the key does
not exist then the original map is returned instead of a new one.

```go
m := immutable.NewMap(nil)
m := immutable.NewMap[string,int](nil)
m = m.Set("jane", 100)
m = m.Delete("jane")

Expand All @@ -193,7 +193,7 @@ pairs in the collection. Unlike Go maps, iterators are deterministic when
iterating over key/value pairs.

```go
m := immutable.NewMap(nil)
m := immutable.NewMap[string,int](nil)
m = m.Set("jane", 100)
m = m.Set("susy", 200)

Expand All @@ -215,11 +215,11 @@ keys generate the same hash.
### Efficiently building maps

If you are executing multiple mutations on a map, it can be much more efficient
to use the `MapBuilder`. It uses nearly the same API as `Map` except that it
updates a map in-place until you are ready to use it.
to use the `MapBuilder`. It uses nearly the same API as `Map` except that it
updates a map in-place until you are ready to use it.

```go
b := immutable.NewMapBuilder(nil)
b := immutable.NewMapBuilder[string,int](nil)
b.Set("foo", 100)
b.Set("bar", 200)
b.Set("foo", 300)
Expand All @@ -242,9 +242,9 @@ Hashers are fairly simple. They only need to generate hashes for a given key
and check equality given two keys.

```go
type Hasher interface {
Hash(key interface{}) uint32
Equal(a, b interface{}) bool
type Hasher[K constraints.Ordered] interface {
Hash(key K) uint32
Equal(a, b K) bool
}
```

Expand Down Expand Up @@ -278,8 +278,8 @@ Comparers on have one method—`Compare()`. It works the same as the
`1` if a is greater than `b`, and returns `0` if `a` is equal to `b`.

```go
type Comparer interface {
Compare(a, b interface{}) int
type Comparer[K constraints.Ordered] interface {
Compare(a, b K) int
}
```

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/benbjohnson/immutable

go 1.12
go 1.18

require golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf h1:oXVg4h2qJDd9htKxb5SCpFBHLipW6hXmL3qpUixS2jw=
golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys=
Loading

0 comments on commit d4a6ab5

Please sign in to comment.