{"id":13483647,"url":"https://github.com/lucaong/immutable","last_synced_at":"2025-07-25T14:08:16.972Z","repository":{"id":50097512,"uuid":"50600047","full_name":"lucaong/immutable","owner":"lucaong","description":"Thread-safe, persistent, immutable collections for the Crystal language","archived":false,"fork":false,"pushed_at":"2021-06-04T09:14:53.000Z","size":379,"stargazers_count":201,"open_issues_count":4,"forks_count":11,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-12-10T08:10:53.493Z","etag":null,"topics":["crystal","data-structures","functional-programming","hash","immutable-collections","persistent-data-structure","vector"],"latest_commit_sha":null,"homepage":"","language":"Crystal","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/lucaong.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":"2016-01-28T17:24:57.000Z","updated_at":"2024-11-28T16:32:13.000Z","dependencies_parsed_at":"2022-08-03T19:00:29.622Z","dependency_job_id":null,"html_url":"https://github.com/lucaong/immutable","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaong%2Fimmutable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaong%2Fimmutable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaong%2Fimmutable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucaong%2Fimmutable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucaong","download_url":"https://codeload.github.com/lucaong/immutable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230520393,"owners_count":18238948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["crystal","data-structures","functional-programming","hash","immutable-collections","persistent-data-structure","vector"],"created_at":"2024-07-31T17:01:13.734Z","updated_at":"2024-12-20T01:15:39.701Z","avatar_url":"https://github.com/lucaong.png","language":"Crystal","readme":"[![Build Status](https://github.com/lucaong/immutable/workflows/CI/badge.svg)](https://github.com/lucaong/immutable/actions)\n\n# Immutable\n\nEfficient, thread-safe immutable data structures for Crystal.\n\nWhenever an `Immutable` data structure is \"modified\", the original remains\nunchanged and a modified copy is returned. However, the copy is efficient due to\nstructural sharing. This makes `Immutable` data structures inherently\nthread-safe, garbage collector friendly and performant.\n\nAt the moment, `Immutable` implements the following persistent data structures:\n\n  - `Immutable::Vector`: array-like ordered, integer-indexed collection\n  implementing efficient append, pop, update and lookup operations\n  - `Immutable::Map`: hash-like unordered key-value collection implementing\n  efficient lookup and update operations\n\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  immutable:\n    github: lucaong/immutable\n```\n\n\n## Usage\n\nFor a list of all classes and methods refer to the [API documentation](http://lucaong.github.io/immutable/api/)\n\nTo use the immutable collections, require `immutable` in your code:\n\n```crystal\nrequire \"immutable\"\n```\n\n### Vector ([API docs](http://lucaong.github.io/immutable/api/Immutable/Vector.html))\n\n```crystal\n# Vector behaves mostly like an Array:\nvector = Immutable::Vector[1, 2, 3, 4, 5]  # =\u003e Vector [1, 2, 3, 4, 5]\nvector[0]                                  # =\u003e 1\nvector[-1]                                 # =\u003e 5\nvector.size                                # =\u003e 5\nvector.each { |elem| puts elem }\n\n# Updating a Vector always returns a modified copy:\nvector2 = vector.set(2, 0)                 # =\u003e Vector [1, 2, 0, 4, 5]\nvector2 = vector2.push(42)                 # =\u003e Vector [1, 2, 0, 4, 5, 42]\n\n# The original vector is unchanged:\nvector                                     # =\u003e Vector [1, 2, 3, 4, 5]\n\n# Bulk updates can be made faster by using `transient`:\nvector3 = vector.transient do |v|\n  1000.times { |i| v = v.push(i) }\nend\n```\n\n### Map ([API docs](http://lucaong.github.io/immutable/api/Immutable/Map.html))\n\n```crystal\n# Map behaves mostly like a Hash:\nmap = Immutable::Map[{:a =\u003e 1, :b =\u003e 2 }]  # =\u003e Map {:a =\u003e 1, :b =\u003e 2}\nmap[:a]                                  # =\u003e 1\n\n# Updating a Map always returns a modified copy:\nmap2 = map.set(:c, 3)                      # =\u003e Map {:a =\u003e 1, :b =\u003e 2, :c =\u003e 3}\nmap2 = map2.delete(:b)                     # =\u003e Map {:a =\u003e 1, :c =\u003e 3}\n\n# The original map in unchanged:\nmap                                        # =\u003e Map {:a =\u003e 1, :b =\u003e 2}\n\n# Bulk updates can be made faster by using `transient`:\nmap3 = Immutable::Map(String, Int32)[]\nmap3 = map3.transient do |m|\n  1000.times { |i| m = m.set(i.to_s, i) }\nend\n```\n\n### Nested structures\n\n```crystal\n# Nested arrays/hashes can be turned into immutable versions with the `.from`\n# method:\n\nnested = Immutable.from({:name =\u003e \"Ada\", :colors =\u003e [:blue, :green, :red] })\nnested # =\u003e Map {:name =\u003e \"Ada\", :colors =\u003e Vector [:blue, :green, :red]}\n```\n\n\n## Implementation\n\n`Immutable::Vector` is implemented as a bit-partitioned vector trie with a block\nsize of 32 bits, that guarantees O(Log32) lookups and updates, which is\neffectively constant time for practical purposes. Due to tail optimization,\nappends and pop are O(1) 31 times out of 32, and O(Log32) 1/32 of the times.\n\n`Immutable::Map` uses a bit-partitioned hash trie with a block size of 32 bits,\nthat also guarantees O(Log32) lookups and updates.\n\n\n## Contributing\n\n1. Fork it ( https://github.com/lucaong/immutable/fork )\n2. Create your feature branch (git checkout -b my-new-feature)\n3. Commit your changes (git commit -am 'Add some feature')\n4. Push to the branch (git push origin my-new-feature)\n5. Create a new Pull Request\n\n\n## Contributors\n\n- [lucaong](https://github.com/lucaong) Luca Ongaro - creator, maintainer\n\n\n## Acknowledgement\n\nAlthough not a port, this project takes inspiration from similar libraries and\npersistent data structure implementations like:\n\n  - [Clojure persistent collections](http://clojure.org/reference/data_structures)\n  - [The Hamster gem for Ruby](https://github.com/hamstergem/hamster)\n\nWhen researching on the topic of persistent data structure implementation, these\nblog posts have been of great help:\n\n  - [Understanding Clojure's Persistent Vector](http://hypirion.com/musings/understanding-persistent-vector-pt-1) (also [Part 2](http://hypirion.com/musings/understanding-persistent-vector-pt-2), [Part 3](http://hypirion.com/musings/understanding-persistent-vector-pt-3) and [Understanding Clojure's Transients](http://hypirion.com/musings/understanding-clojure-transients))\n  - [Understanding Clojure's Persistent Hash Map](http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html)\n\nBig thanks to their authors for the great job explaining the internals of these\ndata structures.\n","funding_links":[],"categories":["Crystal","Misc"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucaong%2Fimmutable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucaong%2Fimmutable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucaong%2Fimmutable/lists"}