GithubHelp home page GithubHelp logo

lucaong / immutable Goto Github PK

View Code? Open in Web Editor NEW
201.0 11.0 11.0 379 KB

Thread-safe, persistent, immutable collections for the Crystal language

License: MIT License

Crystal 98.87% Makefile 1.13%
crystal immutable-collections vector hash data-structures functional-programming persistent-data-structure

immutable's Introduction

Build Status

Immutable

Efficient, thread-safe immutable data structures for Crystal.

Whenever an Immutable data structure is "modified", the original remains unchanged and a modified copy is returned. However, the copy is efficient due to structural sharing. This makes Immutable data structures inherently thread-safe, garbage collector friendly and performant.

At the moment, Immutable implements the following persistent data structures:

  • Immutable::Vector: array-like ordered, integer-indexed collection implementing efficient append, pop, update and lookup operations
  • Immutable::Map: hash-like unordered key-value collection implementing efficient lookup and update operations

Installation

Add this to your application's shard.yml:

dependencies:
  immutable:
    github: lucaong/immutable

Usage

For a list of all classes and methods refer to the API documentation

To use the immutable collections, require immutable in your code:

require "immutable"

Vector (API docs)

# Vector behaves mostly like an Array:
vector = Immutable::Vector[1, 2, 3, 4, 5]  # => Vector [1, 2, 3, 4, 5]
vector[0]                                  # => 1
vector[-1]                                 # => 5
vector.size                                # => 5
vector.each { |elem| puts elem }

# Updating a Vector always returns a modified copy:
vector2 = vector.set(2, 0)                 # => Vector [1, 2, 0, 4, 5]
vector2 = vector2.push(42)                 # => Vector [1, 2, 0, 4, 5, 42]

# The original vector is unchanged:
vector                                     # => Vector [1, 2, 3, 4, 5]

# Bulk updates can be made faster by using `transient`:
vector3 = vector.transient do |v|
  1000.times { |i| v = v.push(i) }
end

Map (API docs)

# Map behaves mostly like a Hash:
map = Immutable::Map[{:a => 1, :b => 2 }]  # => Map {:a => 1, :b => 2}
map[:a]                                  # => 1

# Updating a Map always returns a modified copy:
map2 = map.set(:c, 3)                      # => Map {:a => 1, :b => 2, :c => 3}
map2 = map2.delete(:b)                     # => Map {:a => 1, :c => 3}

# The original map in unchanged:
map                                        # => Map {:a => 1, :b => 2}

# Bulk updates can be made faster by using `transient`:
map3 = Immutable::Map(String, Int32)[]
map3 = map3.transient do |m|
  1000.times { |i| m = m.set(i.to_s, i) }
end

Nested structures

# Nested arrays/hashes can be turned into immutable versions with the `.from`
# method:

nested = Immutable.from({:name => "Ada", :colors => [:blue, :green, :red] })
nested # => Map {:name => "Ada", :colors => Vector [:blue, :green, :red]}

Implementation

Immutable::Vector is implemented as a bit-partitioned vector trie with a block size of 32 bits, that guarantees O(Log32) lookups and updates, which is effectively constant time for practical purposes. Due to tail optimization, appends and pop are O(1) 31 times out of 32, and O(Log32) 1/32 of the times.

Immutable::Map uses a bit-partitioned hash trie with a block size of 32 bits, that also guarantees O(Log32) lookups and updates.

Contributing

  1. Fork it ( https://github.com/lucaong/immutable/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • lucaong Luca Ongaro - creator, maintainer

Acknowledgement

Although not a port, this project takes inspiration from similar libraries and persistent data structure implementations like:

When researching on the topic of persistent data structure implementation, these blog posts have been of great help:

Big thanks to their authors for the great job explaining the internals of these data structures.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.