Javaslang v0.9.0 Release Notes

Release Date: 2017-05-16 // almost 7 years ago
  • ๐Ÿ”„ Changes to the Base Package io.vavr

    ๐Ÿšš We removed the interfaces Kind1 and Kind2. They served as bridge for the removed module javaslang-pure, which contained experimental algebraic extensions.

    Values

    • ๐Ÿšš We removed getOption() in favor of toOption() (which has the same semantics)
    • We changed the functional interface argument of getOrElseTry(CheckedFunction0) (was: getOrElseTry(Try.CheckedSupplier))
    • ๐Ÿšš We removed the conversion method toStack()
    • We replaced the conversion methods
      • toJavaList(Supplier) by toJavaList(Function)
      • toJavaSet(Supplier) by toJavaSet(Function) We added introspection methods isAsync() and isLazy() that provide information about a Value type at runtime We added getOrNull() which returns null if the Value is empty We added Java-like collect() methods We added several conversion methods: toCompletableFuture() toEither(Supplier) toEither(L) toInvalid(Supplier) toInvalid(T) toJavaArray(Class) toJavaCollection(Function) toJavaCollection(Supplier) toJavaList(Function) `toJavaMap(Supplier, Function, Function toJavaParallelStream() toJavaSet(Function) toLinkedMap(Function) toLinkedMap(Function, Function) toLinkedSet() toMap(Function, Function) toPriorityQueue() toPriorityQueue(Comparator) toSortedMap(Comparator, Function) toSortedMap(Comparator, Function, Function) toSortedMap(Function) toSortedMap(Function, Function) toSortedSet() toSortedSet(Comparator) toValid(Supplier) toValid(E) toValidation(Supplier) toValidation(L) ### Functions

    We removed the interface ฮป (the mother of all functions). It was neat but it had no practical purpose. The unicode character caused several problems with 3rd party tools, which did not handle unicode characters properly.

    • ๐Ÿšš We renamed the interface io.vavr.ฮป to io.vavr.Lambda and removed it from the public API.
    • ๐Ÿšš We removed the interface ฮป.Memoized from the public API. We added PartialFunction, which is an enabler for a more performant pattern matching implementation #### Functional interfaces

    With Vavr 0.9 we bundled our functions in io.vavr.

    • ๐Ÿšš We moved the functional interfaces Try.CheckedConsumer, Try.CheckedPredicate, Try.CheckedRunnable to io.vavr.
    • We replaced the functional interface Try.CheckedSupplier by the existing CheckedFunction0.

    ๐Ÿ‘ป Exception Handling

    We added some methods to uncheck an existing throwing function, e.g.CheckedFunction(x -> { throw new Error(); }).unchecked() lift checked functions to an Option return type, e.g.// = NoneCheckedFunction1.lift(x -> { throw new Error(); }).apply(o); lift checked functions to a Try return type, e.g.// = Failure(Error)CheckedFunction1.liftTry(x -> { throw new Error(); }).apply(o);

    Other Factory Methods

    create constant functions, e.g.Function2.constant(1).apply(what, ever); // = 1 narrowing the generic types, e.g. Function0<? extends CharSequence> f_ = () -> "hi"; Function0<CharSequence> f = Function0.narrow(f_);

    Tuples

    • We renamed transform() to apply(), e.g.
      y = f(x1, x2, x3) can be understood as y = Tuple(x1, x2, x3).apply(f). Additions: โšก๏ธ Tuple fields can be updated using one of the update* methods, e.g.Tuple(1, 2, 3).update2(0). A Tuple2 can be swapped, e.g. Tuple(1, 2).swap(). Tuples can be created from java.util.Map.Entry instances, e.g.Tuple.fromEntry(entry) // = Tuple2 Tuples can be sequenced, e.g.Tuple.sequence1(Iterable<? extends Tuple1<? extends T1>>) // = Tuple1<Seq<T1>> Tuples can be narrowed, e.g.Tuple.narrow(Tuple1<? extends T1>) // = Tuple1<T1> ### The API Gateway

    We added io.vavr.API that gives direct access to most of the Vavr API without additional imports.

    We are now able to start using Vavr by adding one gateway import. More imports can be added on demand by the IDE.

    'Companion' Factory Methods

    import static io.vavr.API.*; The new static factory methods serve two things: They add syntactic sugar. E.g. instead of Try.of(() -> new Error()) we now just write Try(() -> new Error()). They reflect the expected return type. Try<Integer> _try = Try(1); Success<Integer> success = Success(1); Failure<Integer> failure = Failure(new Error());

    Option<Integer> option = Option(1); Some<Integer> some = Some(1); None<Integer> none = None();

    Array<Integer> array = Array(1, 2, 3); List<Integer> list = List(1, 2, 3); Stream<Integer> stream = Stream(1, 2, 3); Vector<Integer> vector = Vector(1, 2, 3);

    Tuple1<T> tuple1 = Tuple(t); Tuple3<T, U, V> tuple3 = Tuple(t, u, v); E.g. Some(1) is expected to be Option.Some, not Option. However, type narrowing is possible. // types work as expected Option<CharSeqeuence> option = Some("");

    // str might be null Option<CharSeqeuence> option = Option(str);

    // also possible, it is a Some(null)! Option<CharSeqeuence> option = Some(null);

    Uncheck Functions

    We are now able to uncheck checked functions: Function1<String, User> getUserById = CheckedFunction1.of(id -> throw new IOException()).unchecked(); // = CheckedFunction1.of(User::getById).unchecked(); It is recommended to use the API.unchecked() shortcut instead: Function1<String, User> getUserById = unchecked(id -> throw new IOException()); // = unchecked(User::getById);

    More Syntacic Sugar

    ๐Ÿ–จ We are now able to println to console without having to type the System.out boilerplate. ๐Ÿ–จ println("easy"); Rapid prototyping may require to defer implementations. We use TODO() for that purpose: void fancyNewAlgorithm(Arg arg) { return TODO("some fancy stuff will appear soon"); }

    fancyNewAlgorithm(TODO("need to construct the arg")); The TODO() calls will throw a NotImplementedError at runtime.

    Pattern Matching

    ๐ŸŽ Internally pattern matching now uses the new PartialFunction interface, which gives a performance boost.

    Pattern Names

    We removed the possibility to create pattern matching cases outside of the pattern scope. Now we always use the existing $() methods to lift objects and functions into a pattern context.

    // beforeCase(obj, ...) // e.g. Case(1, ...)Case(predicate, ...) // e.g. Case(t -\> true, ...)// afterCase($(obj), ...) // e.g. Case($(1), ...)Case($(predicate), ...) // e.g. Case($(t -\> true), ...)
    

    Our pattern generator vavr-match follows the new naming scheme and adds a $ to all generated pattern names.

    Please prefix all patterns with $, e.g. $Some(...) instead of Some(...).

    import static io.vavr.API.\*;import static io.vavr.Patterns.\*;// same as `intOption.map(i -\> i * 2).getOrElse(-1)`String result = Match(intOption).of( Case($Some($()), i -\> i \* 2), Case($None(), -1) );
    

    More details here.

    Pre-defined Patterns

    ๐Ÿ›  Accordingly all pattern names in io.vavr.Patterns are now prefixed with a $, and

    • we replaced the List() patterns by $Cons(...) and $Nil().
    • ๐Ÿšš we removed the Stream() patterns because we need to enhance our pattern generator to express inner patterns $Stream.Cons(...) and $Stream.Empty() (API not finished).

    More details here.

    Pre-defined Predicates

    We added the predicates: exists(Predicate) forAll(Predicate) instanceOf(Class) isNotNull() isNull() More details here.

    ๐Ÿ”„ Changes to the Base Package io.vavr.control

    ๐Ÿ‘ป Try keeps original Exception

    • ๐Ÿšš We removed Try.FatalException and Try.NonFatalException
    • Instead we sneaky throw the original exception when calling get() (even if it is checked!)

    ๐Ÿ‘€ For additions see the Try API.

    ๐Ÿ”„ Changes to the Collections io.vavr.collection

    • ๐Ÿšš We removed AbstractIterator from the public API
    • We changed the index type from long to int. That strikes many methods, like take(int), drop(int), zipWithIndex(), ...
    • We removed the unsafe Map.of(Object...) factory methods which interpreted the given objects as pairs.
    • We added the safe Map.of(K, V, ...) factory methods (up to 10 key/value pairs).

    Java Collection Views

    Our sequential collections, i.e. all collections that implement Seq, can be converted to a java.util collection view in O(1). 0๏ธโƒฃ We provide conversion method for mutable and immutable collections. By default collections are immutable, like our persistent collections. java.util.List<Integer> list = Vector(1, 2, 3).asJava(); More examples can be found here.

    More Collections

    We completely re-implemented Vector.

    We added more collections: BitSet PriorityQueue Multimap: HashMultimap and LinkedHashMultimap SortedMultimap: TreeMultimap ๐Ÿ“„ The collections got many additions. Please check out the API docs for further details.