Milestone 6 of Cyclops X
Cyclops-reactive-collections is the last module to be created for Cyclops X (released in Milestone 6). Cyclops lazy and reactive extended collection types move out of the core into their own module, where they can be configured to run powered by Cyclops’ ReactiveSeq or by asynchronous streams in RxJava/2 or Pivotal’s Reactor.
Cyclops Reactive Collections are a suite of extensions for JDK and Persistent Collection types that support a large range of operators as well as (smart) lazy execution of chained operators to drive performance and asynchronous data flows through those operators.
As well as providing configuration options for the reactive engine powering the collections, it is possible to configure the collection types used. E.g. we can switch between Cyclops persistent collections or Vavr persistent collections.
The core of cyclops has been refactored to use Cyclops’ own eager persistent data structures (such as Vector, Seq and LazySeq).
Other improvements in this release include
- Integration with KindedJ which provides a standard interface for simulated Higher Kinded types on the JVM (also used in the Arrow library for Kotlin)
- A much enhanced LazyString implementation
- More consistent naming of grouped and append method suites
- cyclops-pure refactored to use cyclops persistent data types rather than extended collections
- AnyM based monad transformers for core Cyclops Data types (OptionT, VectorT, LazySeqT, SeqT)
Enhanced performance via laziness
Chaining combinator operations on traditional functional datastructures such as the core persistent data structures provided in cyclops.data (or in Vavr or the Scala SDK) results in traversing the datastructure multiple times, once per combinator operation.
E.g. to transform and filter a Cyclops Vector we could write code like the following
Vector.of(1,2,3)
.map(i->i*100)
.filter(i->i<200);
Each of the chained operations will traverse the Vector, once for map and once for filter.
With Cyclops Reactive Collections VectorX the code remains very similar, the underlying datastructure remains identical, but the performance is much improved
VectorX.of(1,2,3)
.map(i->i*100)
.filter(i->i<200);
VectorX in contrast to a raw Vector traverses the underlying data structure just once.
Performance improvement for Vavr's Vector when used with Cyclops VectorX
Lower score is better
- Raw Vavr Vector is on the Right.
- Vavr Vector with Cyclops VectorX is on the left.
Reactive Collections!
In the example below we asynchronously populate an Xtended list using an asynchronously executing ReactiveSeq. Additional reactive operations can be performed on the List asynchronously.
The ListX only blocks on first access to the data.
AtomicBoolean complete = new AtomicBoolean(false);
ReactiveSeq<Integer> async = Spouts.async(ReactiveSeq.of(1,2,3),Executors.newFixedThreadPool(1));
ListX<Integer> asyncList = ListX.listX(async)
.map(i->i+1);
System.out.println("Blocked? " + complete.get());
System.out.println("First value is " + asyncList.get(0));
System.out.println("Completed? " + complete.get());
Which will print
Blocked? false
First value is 101
Completed? true
Available data structures
cyclops.collections (mutable / immutable)
| type | description | characteristics |
|------|-------------|-----------------|
| ListX | Functional extensions for working with Lists | Optionally Reactive or Coreactive, Lazy, mutable, immutable, 3rd party support, Higher kinded |
| DequeX | Functional extensions for working with Deques | Optionally Reactive or Coreactive, Lazy, mutable, immutable, 3rd party support, Higher kinded |
| QueueX | Functional extensions for working with Queues | Optionally Reactive or Coreactive, Lazy, mutable, immutable, 3rd party support, Higher kinded |
| SetX | Functional extensions for working with Sets | Optionally Reactive or Coreactive, Lazy , mutable, immutable, 3rd party support |
| SortedSetX | Functional extensions for working with SortedSets | Optionally Reactive or Coreactive, Lazy, mutable, immutable |
| MapX | Functional extensions for working with Maps | Eager, mutable, immutable |
cyclops.collections.persistent
| type | description | characteristics |
|------|-------------|-----------------|
| LinkedListX | Functional extensions for working with persistent Lists | Optionally Reactive or Coreactive, Lazy, persistent, 3rd party support, Higher kinded |
| VectorX | Functional extensions for working with persistent Vectors | Optionally Reactive or Coreactive, Lazy, persistent, 3rd party support, Higher kinded |
| PersistentSetX | Functional extensions for working with persistent Sets | Optionally Reactive or Coreactive, Lazy, persistent, 3rd party support |
| OrderedSetX | Functional extensions for working with persistent Ordered Sets | Optionally Reactive or Coreactive, Lazy, persistent, 3rd party support |
| PersistentQueueX | Functional extensions for working with persistent Queues | Optionally Reactive or Coreactive, Lazy, persistent, 3rd party support, Higher kinded |
| BagX | Functional extensions for working with persistent Bags (set like collections that allow duplicates) | Optionally Reactive or Coreactive,Lazy, persistent, 3rd party support |
Examples
Lazy execution using extended Collections
Eval<Integer> lazyResult = ListX.of(1,2,3,4)
.map(i->i*10)
.foldLazy(s->s
.reduce( 50,(acc,next) -> acc+next));
Articles
Cyclops X
Cyclops X (cyclops 10) unifies cyclops-react and the cyclops integration modules on the cyclops versioning scheme. The goal of this project is remove a whole class of runtime errors from application code by providing much stricter APIs that prevent exceptional states from arising. A secondary goal is to modularize cyclops into a series of smaller more focused projects so that functionality is easy to find and developers only take what they need.
What’s new Cyclops X
-> Enhancements over cyclops-react 2
- Fast purely functional datastructures (Vector, Seq / List, LazySeq / LazyList, NonEmptyList, HashSet, TreeSet, TrieSet, HashMap, LinkedMap, MultiMap, TreeMap, BankersQueue, LazyString, Discrete Interval Encoded Tree, Zipper, Range, Tree, DifferenceList, HList, Dependent Map )
- Structural Pattern Matching API (deconstruct algebraic product and sum types)
- Improved type safety via the removal of unsafe APIs
-- E.g. Unlike Optional, Option has no get method (which could throw a null pointer)
-- New data structures do not support operations that would throw exceptions (you can't call head on an empty list for example)
- Eager and Lazy alternatives for most datastructures (Option is eager, Maybe is lazy + reactive)
- Improved naming of types (Function1-8 rather than Fn1-8, Either not Xor)
- Group id is changed to com.oath.cyclops
- Versioning between cyclops-react and cyclops is merged on cyclops versioning scheme (version 10 = Cyclops X)
- Light weight dependencies : reactive-streams API & Agrona
What’s new Cyclops X Milestone 5
- Pure functional programming Module
- flatMap and map Operators on Trampoline
- reactive-streams based IO Monad
- Safe PartialFunction API
Changelog
Check out the features delivered and bugs fixed -
github 10.0.0-M6 issues & PRs
Dependency changes
Cyclops no longer depends on pCollections or jOOλ
Get cyclops X
Gradle
Cyclops
compile 'com.oath.cyclops:cyclops:10.0.0-M6’
Cyclops AnyM
compile 'com.oath.cyclops:cyclops-anym:10.0.0-M6’
Cyclops Futurestream
compile 'com.oath.cyclops:cyclops-futurestream:10.0.0-M6’
Cyclops Pure
compile 'com.oath.cyclops:cyclops-pure:10.0.0-M6’
Cyclops Reactive Collections
compile 'com.oath.cyclops:cyclops-reactive-collections:10.0.0-M6’
Maven
Cyclops
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops</artifactId>
<version>10.0.0-M6</version>
</dependency>
Cyclops AnyM
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops-anym</artifactId>
<version>10.0.0-M6</version>
</dependency>
Cyclops Futurestream
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops-anym</artifactId>
<version>10.0.0-M6</version>
</dependency>
Cyclops Pure
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops-pure</artifactId>
<version>10.0.0-M6</version>
</dependency>
Cyclops Reactive Collections
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops-reactive-collections</artifactId>
<version>10.0.0-M6</version>
</dependency>
Documentation
Articles
Old simple-react landing page
License
cyclops-react is licensed under the Apache 2.0 license.
http://www.apache.org/licenses/LICENSE-2.0#
Source code(tar.gz)
Source code(zip)