usethesource / capsule

The Capsule Hash Trie Collections Library
BSD 2-Clause "Simplified" License
404 stars 27 forks source link

Tutorial available? #27

Closed axkr closed 2 years ago

axkr commented 2 years ago

Best practice?

msteindorfer commented 2 years ago

Hi Axel, thanks for reaching out.

Is there a data structure for persistent lists?

No, unfortunately, a persistent list is missing. The intention is to add persistent lists as well, but there is no timeline for this.

Is there a tutorial available how to use PersistentTrieMap API?

No, unfortunately, there is no tutorial available at this time. Thanks for bringing this subject up, I'll consider adding one.

How to use the __... methods? How to best initialize the structure?

In the meantime, please take a look a the examples below that illustrate the usage of the API.

Examples

The __ prefixes were originally introduced to avoid clashes with java.util.Set and java.util.Map methods, while using otherwise the same terminology. (The Capsule data structures do implement the corresponding Java interfaces, though the Java interfaces were designed with mutability in mind.)

When using java.util.Map mutator methods, like put or remove, the PersistentTrieMap would behave the same as an unmodifiable map in Java and throw an UnsupportedOperationException. (See also Creating Unmodifiable Copies of Collections in the Java Core Libraries documentation.)

Thus with the Capsule data structures, you would use the __ prefixed equivalents for manipulating the data structure (e.g., __put or __remove).

Capsule data structures support two different states:

  1. immutable/persistent (default)
  2. transient (temporary via explicit conversions)

The latter is a form of temporary transactional mutability that can be used for efficient batch updates (e.g., efficient initialization, or improving the performance of multiple adjacent updates). See https://clojure.org/reference/transients for the rationale behind the design.

Example - Setup a jshell environment to experiment with the API:

$ curl -OL https://nexus.usethesource.io/service/local/repositories/releases/content/io/usethesource/capsule/0.6.3/capsule-0.6.3.jar

$ jshell --class-path ./capsule-0.6.3.jar

jshell> import io.usethesource.capsule.Map

Example - Use fluent immutable API to create new map versions with added key-value pairs:

jshell> var mapWithKeys1 = Map.Immutable.of(1, "one")
mapWithKeys1 ==> {1: one}

jshell> var mapWithKeys123 = mapWithKeys1.__put(2, "two").__put(3, "three")
mapWithKeys123 ==> {1: one, 2: two, 3: three}

jshell> mapWithKeys1
mapWithKeys1 ==> {1: one}

jshell> mapWithKeys123
mapWithKeys123 ==> {1: one, 2: two, 3: three}

Example - Use mutable API for aggregating multiple subsequent mutations:

jshell> var tmp = mapWithKeys1.asTransient()
jshell> tmp.__put(2, "two")
jshell> tmp.__put(3, "three")
jshell> tmp.__put(4, "four")
jshell> var mapWithKeys1234 = tmp.freeze()
mapWithKeys1234 ==> {1: one, 2: two, 3: three, 4: four}

jshell> mapWithKeys1
mapWithKeys1 ==> {1: one}

jshell> mapWithKeys1234
mapWithKeys1234 ==> {1: one, 2: two, 3: three, 4: four}

Example - Start with the mutable API for efficiently initializing a map:

jshell> var tmp = Map.Transient.of()
jshell> tmp.__putAll(java.util.Map.of(1, "one", 2, "two", 3, "three", 4, "four"))
jshell> tmp.freeze()
$1 ==> {1: one, 2: two, 3: three, 4: four}
axkr commented 2 years ago

Tnaks for your help. I've now switched to Paguro because I also needed list collection: