immutable

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2024 License: BSD-3-Clause Imports: 4 Imported by: 2

README

PkgGoDev Go Report Card

go-immutable

Immutable map/set/list for go.

Benchmark

This library comes with benchmark test to compare against builtin types (there's no builtin set so that's only list and map). Here is an example of the benchmark result (with baseline is builtin):

$ go test -bench .
goos: linux
goarch: amd64
pkg: go.yhsif.com/immutable
cpu: 12th Gen Intel(R) Core(TM) i5-1235U
BenchmarkListBuilder/literal-10/baseline-12             1000000000               0.1226 ns/op          0 B/op          0 allocs/op
BenchmarkListBuilder/literal-10/immutable-12             8853948               138.0 ns/op           288 B/op          5 allocs/op
BenchmarkListBuilder/10/baseline-12                     35211993                30.00 ns/op           80 B/op          1 allocs/op
BenchmarkListBuilder/10/immutable-12                     7969965               141.7 ns/op           288 B/op          5 allocs/op
BenchmarkListBuilder/1024/baseline-12                     633338              1818 ns/op            8192 B/op          1 allocs/op
BenchmarkListBuilder/1024/immutable-12                    234624              5069 ns/op           24624 B/op          5 allocs/op
BenchmarkListBuilder/131072/baseline-12                     8010            145301 ns/op         1048578 B/op          1 allocs/op
BenchmarkListBuilder/131072/immutable-12                    1563            846922 ns/op         3145783 B/op          5 allocs/op
BenchmarkListRange/10/baseline-12                       861452865                1.387 ns/op           0 B/op          0 allocs/op
BenchmarkListRange/10/immutable-12                      83046913                14.07 ns/op            0 B/op          0 allocs/op
BenchmarkListRange/10/immutable-all-12                  14067778                77.32 ns/op           48 B/op          3 allocs/op
BenchmarkListRange/1024/baseline-12                      8330391               132.3 ns/op             0 B/op          0 allocs/op
BenchmarkListRange/1024/immutable-12                      969414              1187 ns/op               0 B/op          0 allocs/op
BenchmarkListRange/1024/immutable-all-12                  877918              1373 ns/op              48 B/op          3 allocs/op
BenchmarkListRange/131072/baseline-12                      79238             15261 ns/op               0 B/op          0 allocs/op
BenchmarkListRange/131072/immutable-12                      7893            154461 ns/op               0 B/op          0 allocs/op
BenchmarkListRange/131072/immutable-all-12                  6350            176498 ns/op              48 B/op          3 allocs/op
BenchmarkMapBuilder/literal-5/baseline-12               29004186                43.80 ns/op            0 B/op          0 allocs/op
BenchmarkMapBuilder/literal-5/immutable-12               1931334               629.7 ns/op           688 B/op         12 allocs/op
BenchmarkMapBuilder/10/baseline-12                       4204045               282.5 ns/op           292 B/op          1 allocs/op
BenchmarkMapBuilder/10/immutable-literal-12               720141              1551 ns/op            1562 B/op         15 allocs/op
BenchmarkMapBuilder/10/immutable-builder-12              1233813               980.9 ns/op          1031 B/op         10 allocs/op
BenchmarkMapBuilder/1024/baseline-12                       19167             60340 ns/op           86568 B/op         64 allocs/op
BenchmarkMapBuilder/1024/immutable-literal-12               5065            220412 ns/op          260301 B/op        201 allocs/op
BenchmarkMapBuilder/1024/immutable-builder-12               7386            144569 ns/op          173537 B/op        134 allocs/op
BenchmarkMapBuilder/131072/baseline-12                       124          10252703 ns/op        10925729 B/op       4766 allocs/op
BenchmarkMapBuilder/131072/immutable-literal-12               32          36882045 ns/op        32773405 B/op      14277 allocs/op
BenchmarkMapBuilder/131072/immutable-builder-12               57          20891777 ns/op        21850429 B/op       9529 allocs/op
BenchmarkMapRange/10/baseline-12                        14706384                78.00 ns/op            0 B/op          0 allocs/op
BenchmarkMapRange/10/immutable-12                       13813046                89.78 ns/op            0 B/op          0 allocs/op
BenchmarkMapRange/10/immutable-all-12                    7471460               167.3 ns/op            48 B/op          3 allocs/op
BenchmarkMapRange/1024/baseline-12                        122810              8322 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/1024/immutable-12                       134680              8906 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/1024/immutable-all-12                   126817              9122 ns/op              48 B/op          3 allocs/op
BenchmarkMapRange/131072/baseline-12                        1198           1060454 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/131072/immutable-12                       1054           1139414 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/131072/immutable-all-12                   1010           1230834 ns/op              48 B/op          3 allocs/op
PASS
ok      go.yhsif.com/immutable  53.351s

License

BSD License.

Documentation

Overview

Package immutable provides immutable data structures (map/set/list).

Note that immutable map/set/list only guarantee the immutability of the container itself, not the content inside. For example if you are using a immutable list of pointers, you are guaranteed that you always get the same pointer with the same index, but the content pointer points to might be changed by others sharing the same immutable list.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrBreak = errors.New("immutable: stop iteration")

ErrBreak can be used in Range functions to stop the iteration early.

Functions

This section is empty.

Types

type List

type List[T any] interface {
	// Len returns the length of the list.
	Len() int

	// Get returns the i-th item with 0-index.
	//
	// It panics when i is out of [0, Len()-1].
	Get(i int) T

	// Range iterates through the list, in its original order.
	//
	// It will return the error returned by f.
	Range(f ListRangeFunc[T]) error

	// All implements iter.Seq2[index, value].
	All() iter.Seq2[int, T]

	// Reslice returns the sublist from start to end-1 index.
	//
	// Use out of range indices will cause panic.
	Reslice(start, end int) List[T]
}

List defines the interface of an immutable list.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	list := immutable.ListLiteral("a", "b", "c")
	fmt.Println("Len:", list.Len())
	fmt.Println("list.Get(1):", list.Get(1))
	fmt.Println("Break iteration:")
	list.Range(func(i int, x string) error {
		if i >= 1 {
			return immutable.ErrBreak
		}
		fmt.Printf("%d: %v\n", i, x)
		return nil
	})
	fmt.Println("Full iteration:")
	list.Range(func(i int, x string) error {
		fmt.Printf("%d: %v\n", i, x)
		return nil
	})
	fmt.Printf("%%v: %v\n", list)
	fmt.Println("Reslice(1, 3):", list.Reslice(1, 3))
}
Output:

Len: 3
list.Get(1): b
Break iteration:
0: a
Full iteration:
0: a
1: b
2: c
%v: [a b c]
Reslice(1, 3): [b c]

func EmptyList added in v0.1.1

func EmptyList[T any]() List[T]

EmptyList returns an immutable empty list.

func ListLiteral

func ListLiteral[T any](items ...T) List[T]

ListLiteral creates an immutable list from items.

It's shorthand for immutable.NewListBuilder[T]().Append(items...).Build().

type ListBuilder

type ListBuilder[T any] interface {
	List[T]

	// Append appends item(s) to the list.
	//
	// It returns self for chaining.
	Append(x ...T) ListBuilder[T]

	// Build builds the immutable list.
	Build() List[T]
}

ListBuilder defines the interface of an immutable list builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewListBuilder

func NewListBuilder[T any]() ListBuilder[T]

NewListBuilder creates a ListBuilder.

type ListRangeFunc

type ListRangeFunc[T any] func(i int, x T) error

ListRangeFunc defines the iteration function for List type.

i will be the 0-based index and x will be the item.

Whenever ListRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

type Map

type Map[K comparable, V any] interface {
	// Len returns the size of the map.
	Len() int

	// Load returns the value to the key.
	//
	// If the key is not in the map, value will be zero and ok will be false.
	Load(key K) (value V, ok bool)

	// Get returns the value to the key.
	//
	// It's the same as Load just without ok return.
	Get(key K) V

	// Range iterates through the map.
	//
	// It will return the error returned by f.
	Range(f MapRangeFunc[K, V]) error

	// All implements iter.Seq2[key, value].
	All() iter.Seq2[K, V]
}

Map defines the interface of an immutable map.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	m := immutable.MapLiteral(map[int]string{
		1: "a",
	})
	fmt.Printf("%%v: %v\n", m)
	m = immutable.MapLiteral(map[int]string{
		1: "a",
		2: "b",
		3: "c",
	})
	fmt.Println("Len:", m.Len())
	fmt.Println("m.Get(1):", m.Get(1))
	fmt.Println("range:")
	m.Range(func(k int, v string) error {
		fmt.Printf("%v: %v\n", k, v)
		return nil
	})
}
Output:

%v: map[1:a]
Len: 3
m.Get(1): a
range:
1: a
2: b
3: c

func EmptyMap added in v0.1.1

func EmptyMap[K comparable, V any]() Map[K, V]

EmptyMap returns an immutable empty map.

func MapLiteral

func MapLiteral[K comparable, V any](m map[K]V) Map[K, V]

MapLiteral creates an immutable map from existing map.

It's shorthand for immutable.NewMapBuilder[K, V]().Update(m).Build().

type MapBuilder

type MapBuilder[K comparable, V any] interface {
	Map[K, V]

	// Set sets the key value pair to the map.
	//
	// It returns self for chaining.
	Set(key K, value V) MapBuilder[K, V]

	// Update updates every key value pair from m to the map.
	//
	// It returns self for chaining.
	Update(m map[K]V) MapBuilder[K, V]

	// Build builds the immutable map.
	Build() Map[K, V]
}

MapBuilder defines the interface of an immutable map builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewMapBuilder

func NewMapBuilder[K comparable, V any]() MapBuilder[K, V]

NewMapBuilder creates a new MapBuilder.

type MapRangeFunc

type MapRangeFunc[K comparable, V any] func(key K, value V) error

MapRangeFunc defines the iteration function for Map type.

Whenever MapRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

type Set

type Set[T comparable] interface {
	// Len returns the length of the set.
	Len() int

	// Contains checks whether an item is in the set.
	Contains(x T) bool

	// Range iterates through the set.
	//
	// It will return the error returned by f.
	Range(f SetRangeFunc[T]) error

	// All implements iter.Seq[value].
	All() iter.Seq[T]
}

Set defines the interface of an immutable set.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	s := immutable.SetLiteral("a")
	fmt.Printf("%%v: %v\n", s)
	s = immutable.SetLiteral("a", "b", "c")
	fmt.Println("Len:", s.Len())
	fmt.Println(`s.Contains("a"):`, s.Contains("a"))
	fmt.Println(`s.Contains("d"):`, s.Contains("d"))
	fmt.Println("range:")
	s.Range(func(x string) error {
		fmt.Printf("%v\n", x)
		return nil
	})
}
Output:

%v: [a]
Len: 3
s.Contains("a"): true
s.Contains("d"): false
range:
a
b
c

func EmptySet added in v0.1.1

func EmptySet[T comparable]() Set[T]

EmptySet returns an immutable empty set.

func SetLiteral

func SetLiteral[T comparable](items ...T) Set[T]

SetLiteral creates an immutable set from items.

It's shorthand for immutable.NewSetBuilder[T]().Add(items...).Build().

type SetBuilder

type SetBuilder[T comparable] interface {
	Set[T]

	// Add adds item(s) to the set.
	//
	// It returns self for chaining.
	Add(x ...T) SetBuilder[T]

	// Build builds the immutable set.
	Build() Set[T]
}

SetBuilder defines the interface of an immutable set builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewSetBuilder

func NewSetBuilder[T comparable]() SetBuilder[T]

NewSetBuilder creates a new SetBuilder.

type SetRangeFunc

type SetRangeFunc[T comparable] func(x T) error

SetRangeFunc defines the iteration function for Set type.

Whenever SetRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL