ianthehenry / jimmy

Janet bindings for the persistent data structure library "immer"

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

jimmy

Janet bindings for immer, a library of immutable data structures.

(use jimmy)

(def good-numbers (set/new 1 2 3 4 5))
(print good-numbers)
#| {2 3 5 1 4}

# actually, five kinda sucks
(print (set/remove good-numbers 5))
#| {2 3 1 4}

# but it was persistent all along!!
(print good-numbers)
#| {2 3 5 1 4}

# sets support union/intersect/difference, and
# operators are standing by
(print (- good-numbers (set/new 1 2)))
#| {3 5 4}

You can (use jimmy) to bring all types into scope as set/new, map/new, etc., or you can (import jimmy/set) to only bring a specific submodule into scope.

Note: the jimmy/map module is extremely incomplete.

API

jimmy/set

Functions

(set/add set & xs)

Returns a new set containing all of the elements from the original set and all of the subsequent arguments.


(set/count set pred)

Returns the number of elements in the set that match the given predicate. pred can be any callable value, not just a function.

Note that the arguments are in a different order than Janet's count function.


(set/difference set & sets)

Returns a set that is the first set minus all of the latter sets.


(set/filter set pred)

Returns a set containing only the elements for which the predicate returns a truthy value. pred can be any callable value, not just a function.

Note that the arguments are in the opposite order of Janet's filter function.


(set/filter-map set f)

Like set/map, but excludes nil. f can be any callable value, not just a function.


(set/intersection & sets)

Returns a set that is the intersection of all of its arguments. Naively folds when given more than two arguments.


(set/map set f)

Returns a new set derived from the given transformation function. f can be any callable value, not just a function.

Note that the arguments are in the opposite order of Janet's map function.


(set/new & xs)

Returns a persistent immutable set containing only the listed elements.


(set/of iterable)

Returns a set of all the values in an iterable data structure.


(set/of-keys iterable)

Returns a set of all the keys in an iterable data structure.


(set/reduce set init f)

Returns a reduction of the elements in the set, which will be traversed in arbitrary order. f can be any callable value, not just a function.

Note that the arguments are in a different order than Janet's reduce function.


(set/remove set & xs)

Returns a new set containing all of the elements from the original set except any of the subsequent arguments.


(set/strict-subset? a b)

Returns true if a is a strict subset of b.


(set/strict-superset? a b)

Returns true if a is a strict superset of b.


(set/subset? a b)

Returns true if a is a subset of b.


(set/superset? a b)

Returns true if a is a superset of b.


(set/to-array set)

Returns an array of all of the elements in the set, in no particular order.


(set/to-tuple set)

Returns a tuple of all of the elements in the set, in no particular order.


(set/union & sets)

Returns a set that is the union of all of its arguments.

Methods

  • :+ is an alias for set/union
  • :* is an alias for set/intersection
  • :- is an alias for set/difference

Values

  • set/empty is the empty set

jimmy/map

Functions

(map/keys map)

Returns an iterator over the keys in the map.


(map/new & kvs)

Returns a persistent immutable map containing the listed entries.


(map/pairs map)

Returns an iterator over the key-value pairs in the map.


(map/values map)

Returns an iterator over the values in the map.

Values

  • map/empty is the empty map

jimmy/vec

Functions

(vec/count vec pred)

Returns the number of elements in the vector that match the given predicate. pred can be any callable value, not just a function.

Note that the arguments are in a different order than Janet's count function.


(vec/filter vec pred)

Returns a vector containing only the elements for which the predicate returns a truthy value. pred can be any callable value, not just a function.

Note that the arguments are in the opposite order of Janet's filter function.


(vec/filter-map vec f)

Like vec/map, but excludes nil. f can be any callable value, not just a function.


(vec/first vec)

Returns the first element of the vector.


(vec/last vec)

Returns the last element of the vector.


(vec/map vec f)

Returns a new vector derived from the given transformation function. f can be any callable value, not just a function.

Note that the arguments are in the opposite order of Janet's map function.


(vec/new & xs)

Returns a persistent immutable vector containing only the listed elements.


(vec/of iterable)

Returns a vector of all the values in an iterable data structure.


(vec/pop vec)

Returns a new vector with the last element removed.


(vec/popn vec)

Returns a new vector with the last n elements removed.


(vec/push vec & xs)

Returns a new vector containing all of the elements from the original and all of the subsequent arguments.


(vec/put vec n val)

Returns a new vector with nth element set to val.


(vec/reduce vec init f)

Returns a reduction of the elements in the vector. f can be any callable value, not just a function.

Note that the arguments are in a different order than Janet's reduce function.


(vec/take vec n)

Returns a new vector containing the first n elements of vec, or all of vec if n >= (length vec).


(vec/to-array vec)

Returns an array of all of the elements in the vector.


(vec/to-tuple vec)

Returns a tuple of all of the elements in the vector.

Values

  • vec/empty is the empty vector

Gotchas

Janet's iteration protocol is not flexible enough for Jimmy to support eachk or eachp or the :keys and :pairs directive in loop-family macros.

Unlike Janet's tables and structs, Jimmy data structures can contain nil:

repl:1:> (use jimmy)
repl:2:> (set/new 1 2 3 nil)
<jimmy/set {3 1 nil 2}>
repl:3:> (map/new nil :value :key nil)
<jimmy/map {nil :value :key nil}>

Iterating over a map with each will iterate over key-value pairs, not just values. To iterate over values, use:

(each value (map/values map)
  (print value))

You should not use eachk or eachp with Jimmy maps, because next returns an iterator, not a key. To iterate over the keys in a map, use:

(each value (map/keys map)
  (print value))

In order to support iteratation with Janet's next protocol for unordered containers, Jimmy boxes the corresponding C++ iterator into an abstract type to use as the key. This means that a simple (each el set (print el)) will allocate memory for the abstract type containing the iterator. It's not a lot of memory, but it's short-lived garbage and Janet's GC currently does nothing to optimize for short-lived garbage. This probably won't cause performance problems, just something to bear in mind.

Also, I don't know C++, which is sort of a flaw when trying to write bindings for a C++ library, so I would caution you to read the code with a very critical eye. Code review welcome!

TODO

  • add bindings for immer::map
  • 1.0 release

About

Janet bindings for the persistent data structure library "immer"

License:MIT License


Languages

Language:C++ 77.2%Language:Janet 22.8%