y is a functional library for Kotlin multiplatform that aims to port andprovide effective concepts inspired by other languages, libraries or even paradigms.
N.B.: This library is heavily inspired by Clojure
Modules:
y-core:
This module provides core and utility functions that may or may not collaborate with other modules (e.g. y-collections) to fulfill their purpose.
y-collections:
This module is basically a port of some of Clojure data structures such as collections, symbols and keywords. Unlike Clojure, collections in y do support generics so you can specify types while creating a list or a map etc.
N.B.: PersistentHashMap implementation was ported from bendyworks implementation since it is based on the latest research of Michael J. Steindorfer & Jurgen J. Vinju
-
Data structures:
-
Collections :
-
PersistentList:
val list1 : PersistentList<Int> = l<Int>(1,2,3) // (1 2 3) val empty : PersistentList<Int> = l<Int>() // () // From Kotlin's List<E> to PersistentList<E> val list2 : PersistentList<Int> = listOf<Int>(1, 2, 3).toPlist() // (1 2 3)
To add an item to a list, use
conj(e)
, it puts the item at the front of the list and returns a new list.l<Int>(1,2,3).conj(4) // (4 1 2 3)
To get the size of a list:
l<Int>(1,2,3).count // 3
-
PersistentVector:
val vec1 : PersistentVector<Int> = v<Int>(1, 2, 3) // [1 2 3] val empty : PersistentVector<Int> = v<Int>() // [] // From Kotlin's List<E> to PersistentVector<E> val vec2 : PersistentList<Int> = listOf<Int>(1, 2, 3).toPvector() // [1 2 3]
To add an item to a vector, use
conj(e)
, it puts the item at the end of the vector and returns a new vector.v<Int>(1, 2, 3).conj(4) // [1 2 3 4]
To get the size of a vector:
v<Int>(1, 2, 3).count // 3
To get an item by index, you can use
get(index)
operator ornth(index)
/nth(index, def)
v<Int>(1, 2, 3)[1] // 2 v<Int>(1, 2, 3).nth(2) // 3 v<Int>(1, 2, 3).nth(5, -1) // -1
To get the items in reverse order as a sequence, use
reverse()
v<Int>(1, 2, 3).reverse() // (3 2 1)
-
PersistentArrayMap<K, V>:
This map should be only used when you have very small maps and want to maintain key order, since it is just an array of
[key,val..key,val]
. Subsequentassoc-ing
will eventually return aPersistentHashMap
.val map1 : PersistentArrayMap<String, Int> = m<String, Int>("1" to 1, "2" to 2) // {"1" 1, "2" 2} //From Kotlin's Map<K,V> to PersistentArrayMap<K,V> val map2 : PersistentArrayMap<String, Int> = mapOf<String, Int>("1" to 1, "2" to 2).toPArrayMap() // {"1" 1, "2" 2}
-
PersistentHashMap<K, V>:
This map requires keys that correctly support hashCode and equals.
val map1 : PersistentHashMap<String, Int> = hashMap<String, Int>("1" to 1, "2" to 2) // {"1" 1, "2" 2} //From Kotlin's Map<K,V> to PersistentHashMap<K,V> val map2 : PersistentHashMap<String, Int> = mapOf<String, Int>("1" to 1, "2" to 2).toPhashMap() // {"1" 1, "2" 2}
-
PersistentHashSet:
val set1 : PersistentHashSet<Int> = hs<Int>(1, 2, 2, 3, 3) // #{1 2 3} //From Kotlin's Set<E> to PersistentHashSet<E> val set2 : PersistentHashSet<Int> = setOf<Int>(1, 2, 2, 3 ,3).toPhashSet() // #{1 2 3}
-
Sequence:
All collections support a member function
seq()
that return a sequence of typeISeq<E>
that can walk the entire collection. A sequance provides three key member functions:first()
: return the first element in the sequence.rest()
: returns all of the rest elements of the sequence that came after first element, as a sequence.cons(element)
: always adds to the front of the sequence and returns a sequence.
-
-
Keywords :
Keywords are identifiers that provide very fast equality tests, and they have a string name. If you call toString() on a keyword it returns the name prefixed by a ':' which is not part of the name.
// To create a Keyword, use the utility function `k(name:String)`: val keyword = k("a") // :a // invoke(map, default = null) operator val map = hashMap("a" to 1) val key = k("a") val default = k("none") key(map, default) // :none
-