{"id":43029052,"url":"https://github.com/phelmkamp/immut","last_synced_at":"2026-01-31T07:33:27.711Z","repository":{"id":40661517,"uuid":"474189258","full_name":"phelmkamp/immut","owner":"phelmkamp","description":"Immutable data structures for the Go language.","archived":false,"fork":false,"pushed_at":"2023-05-04T00:30:08.000Z","size":77,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-17T05:30:53.188Z","etag":null,"topics":["append-only","copy-on-write","freeze","golang","immutable","map","pointer","read-only","slice"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phelmkamp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-25T23:14:40.000Z","updated_at":"2024-04-16T17:15:53.000Z","dependencies_parsed_at":"2023-01-19T20:45:12.928Z","dependency_job_id":null,"html_url":"https://github.com/phelmkamp/immut","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/phelmkamp/immut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fimmut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fimmut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fimmut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fimmut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phelmkamp","download_url":"https://codeload.github.com/phelmkamp/immut/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fimmut/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28933306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T04:05:25.756Z","status":"ssl_error","status_checked_at":"2026-01-31T04:02:35.005Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["append-only","copy-on-write","freeze","golang","immutable","map","pointer","read-only","slice"],"created_at":"2026-01-31T07:33:26.533Z","updated_at":"2026-01-31T07:33:27.700Z","avatar_url":"https://github.com/phelmkamp.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# immut\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/phelmkamp/immut.svg)](https://pkg.go.dev/github.com/phelmkamp/immut)\n[![Go Report Card](https://goreportcard.com/badge/github.com/phelmkamp/immut)](https://goreportcard.com/report/github.com/phelmkamp/immut)\n[![codecov](https://codecov.io/gh/phelmkamp/immut/branch/main/graph/badge.svg?token=79CVDP412S)](https://codecov.io/gh/phelmkamp/immut)\n\nIn Go, immutability is limited to primitive types and structs (via the `const` keyword and pass-by-value respectively).\nThis module provides read-only slices, maps, and pointers via the generic types [`roslices.Slice`](https://pkg.go.dev/github.com/phelmkamp/immut/roslices),\n[`romaps.Map`](https://pkg.go.dev/github.com/phelmkamp/immut/romaps), and [`corptrs.Pointer`](https://pkg.go.dev/github.com/phelmkamp/immut/corptrs).\nThese types may be considered \"zero-cost abstractions\" because the underlying value is not copied.\n\nIn addition, the [`cowslices`](https://pkg.go.dev/github.com/phelmkamp/immut/cowslices) and [`cowmaps`](https://pkg.go.dev/github.com/phelmkamp/immut/cowmaps)\npackages provide copy-on-write semantics. The mutating functions seamlessly clone the underlying value before the write-operation is performed\n\nThe `*slices` and `*maps` packages are drop-in replacements for the standard [slices](https://pkg.go.dev/golang.org/x/exp/slices) and \n[maps](https://pkg.go.dev/golang.org/x/exp/maps) packages. In fact, the unit tests for those packages have been copied here to ensure compatibility.\n\nNote: This project is not intended to replace all uses of slices, maps, and pointers with unnecessary boxed-types. It is specifically for restricting write-access to values of these types in cases where it is desirable to do so.\nFor example:\n * Ensure return values cannot be modified (previously required a defensive copy)\n * Guarantee to callers that function arguments will not change\n * Safely access shared state from multiple goroutines (e.g. values in `context.Context`)\n * Prevent mutation of variables/fields after initialization\n * Pass pointers to large structs and avoid excess copying without the risk of modification\n\n\n## Installation\n\n```bash\ngo get github.com/phelmkamp/immut\n```\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/phelmkamp/immut/cowmaps\"\n\t\"github.com/phelmkamp/immut/cowslices\"\n\t\"github.com/phelmkamp/immut/romaps\"\n\t\"github.com/phelmkamp/immut/corptrs\"\n\t\"github.com/phelmkamp/immut/roslices\"\n\t//\"golang.org/x/exp/maps\"\n\t//\"golang.org/x/exp/slices\"\n)\n\nfunc main() {\n\t// read-only slices\n\ts := roslices.Freeze([]int{1, 2, 3})\n\tfmt.Println(roslices.IsSorted(s))\n\t//slices.Sort(s) // not allowed\n\n\t// copy-on-write slices\n\ts2 := cowslices.CopyOnWrite([]int{2, 1, 3})\n\tcowslices.Sort(\u0026s2)\n\tfmt.Println(s2)\n\n\t// read-only maps\n\tm := romaps.Freeze(map[string]int{\"foo\": 42, \"bar\": 7})\n\tfmt.Println(romaps.Keys(m))\n\t//maps.Clear(m) // not allowed\n\n\t// copy-on-write maps\n\tm2 := cowmaps.CopyOnWrite(map[string]int{\"foo\": 42, \"bar\": 7})\n\tcowmaps.DeleteFunc(\u0026m2, func(k string, v int) bool { return k == \"foo\" })\n\tfmt.Println(m2)\n\n\t// read-only pointers\n\ttype big struct {\n\t\ta, b, c, d, e int\n\t}\n\tb := big{1, 2, 3, 4, 5}\n\tp := corptrs.Freeze(\u0026b)\n\tp2 := p.Clone()\n\tp2.a = 42\n\tfmt.Println(p, p2)\n\t//p.a = 42 // not allowed\n}\n```\n\n## Releases\n\nThis module strives to maintain compatibility with the standard packages `slices` and `maps` that have not yet fully stabilized.\nAs such, it will remain untagged until the corresponding packages are tagged.\nThen, it will remain at v0 until the corresponding packages achieve v1 status.\n\n## Performance\n\nThis project aims to be a zero-cost abstraction of Go's standard types.\nThe Go compiler avoids excess function calls by copying simple function bodies to the call-site through a process called\n[inlining](https://dave.cheney.net/2020/04/25/inlining-optimisations-in-go). \n`Test_inline` verifies that the compiler can inline ~~all~~* many of the read-only functions in this module.\n - *Go 1.19 regression to be restored in Go 1.20\n\nThe copy-on-write functions avoid unnecessary reallocation wherever possible.\nThe [`cowslices.DoAll`](https://pkg.go.dev/github.com/phelmkamp/immut/cowslices#DoAll) function is provided to support multiple write-operations with minimal reallocation.\nBecause of extra checks to avoid copying, most of the copy-on-write functions cannot be inlined by the compiler but that is a conscious tradeoff.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphelmkamp%2Fimmut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphelmkamp%2Fimmut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphelmkamp%2Fimmut/lists"}