Releases: vavr-io/vavr
Patch Release 0.10.5
Vavr is back with a new maintainer, roadmap, and... a release.
This release brings various performance enhancements, bugfixes, and explicit jlink-friendly module declarations instead of automatic modules.
Committers
🎉 MANY THANKS TO ALL COMMITTERS! 🎉
@KrnSaurabh @achinaou @sleepytomcat @j-baker @Kevin222004 @pivovarit
Changes
- Qualify all yield() calls by @pivovarit in #2799
- Fix Array.appendAll() arraycopy type mismatch by @pivovarit in #2795
- Performance improvement for List::unfold, List::unfoldLeft by @sleepytomcat in #2689
- Traversable.zipWithIndex() javadoc fix by @sleepytomcat in #2706
- Faster LinkedHashMap by tail() by @j-baker in #2725
- Actual faster LinkedHashSet tail by @j-baker in #2726
- Faster LinkedHashSet head() by @j-baker in #2728
- minor: make private class final with default constructor by @Kevin222004 in #2740
- Replace synchronized method/block with reentrant lock by @KrnSaurabh in #2845
- Update Scala to 3.5 by @achinaou in #2858
- Suppress Tuple elements serialization warning by @pivovarit in #2872
- Suppress various serialization warnings by @pivovarit in #2873 #2874 #2875 #2876 #2877
- Don't reference ThreadDeath directly due to its future removal by @pivovarit in #2878
- Fix remaining Java Serialization issues with JDK21 by @KrnSaurabh in #2880
- Full Java Platform Module System support for Java 9+ by @pivovarit in #2846
- Various JavaDoc fixes by @pivovarit in #2888 #2889 #2895 #2896 #2897 #2898
Patch Release 0.10.4
Info
This is a maintenance release for the 0.10.x release train. It back ports bug fixes and improvements from the upcoming 1.0.0 release.
Please find the complete list of changes here.
The API Docs can be found here
Committers
🎉 MANY THANKS TO ALL COMMITTERS! 🎉
- ⭐️ anton0xf (@anton0xf)
- ⭐️ Gualtiero Testa (@gualtierotesta)
- ⭐️ Joachim Bargsten (@jwbargsten)
- ⭐️ Mincong Huang (@mincong-h)
- ⭐️ Sergei Semenov (@sleepytomcat)
Changes
- Option<>.collect() not to call PartialFunction collector on arguments where it is not defined (#2580) @sleepytomcat
- Iterate once to create two iterators in partition (#2577) @mincong-h
- Wrong parameter name in Either.filterOrElse JavaDoc (#2618) @gualtierotesta
- Fix Array#update(int, T) complexity (#2648) @anton0xf
- more robust slideby classifier function handling (#2642) @jwbargsten
- Vector.of(T element) performance improvement (#2659) @sleepytomcat
Patch Release 0.10.3
Info
This is a maintenance release for the 0.10.x release train.
Please find the complete list of changes here.
The API Docs can be found here
Committers
🎉 MANY THANKS TO ALL COMMITTERS! 🎉
- ⭐️ Mincong Huang (@mincong-h)
- ⭐️ Daniel Dietrich (@danieldietrich)
Changes
Patch Release 0.10.2
This patch release fixes the bug of overlapping JPMS module names by removing the Automatic-Module-Name
attributes from the MANIFEST.MF files.
The upcoming release v1.0.0 will not have Automatic-Module-Name
attributes.
The next release v2.0.0 will have proper JPMS modules.
Bugfix Release 0.10.1
Info
This is a maintenance release for the 0.10.x release train.
Please find the complete list of changes here.
The API Docs can be found here
Committers
🎉 MANY THANKS TO ALL COMMITTERS! 🎉
- ⭐️ Daniel Dietrich (@danieldietrich)
- ⭐️ Theodor A. Dumitrescu (@thadumi)
- ⭐️ Bram Schuur (@craffit)
Changes
- Bugfix: #2430 Future.reduce considers executor
- Bugfix: #2426 Fixes DistictIterator to not eat null values
- Bugfix: #2405 Fixes patmat corner case that might produce a ClassCastException
- Bugfix: #2403 ClassCastException during pattern matching
- Bugfix: #2399 Fix: CharSeq implements Comparable
- Improvement: #2400 Improve performance of last() call on TreeMap
Preview Release 1.0.0 alpha 3
Info
Caution: This is a preview release of the upcoming major release 1.0.0. It is highly under development and the API is subject to change. Please do not use it in production.
We are still in the process of moving the changes from the original 1.0.0 branch to master.
Additionally there are stashed changes that did not make it into the minor release 0.10.0, that may make it into the upcoming 1.0.0 release. This is also work in progress.
The API Docs can be found here (🚧 currently unavailable because https://www.javadoc.io seems to be down)
Comitters
🎉 MANY THANKS TO ALL COMMITTERS! 🎉
- ⭐️ Daniel Dietrich (@danieldietrich)
- ⭐️ baant
- ⭐️ Alexandru Stana (alexandrustana)
- ⭐️ Mark Raynsford (io7m)
- ⭐️ Theodor A. Dumitrescu (@thadumi)
- ⭐️ Juan Antonio Breña Moral (jabrena)
- ⭐️ Bram Schuur (@craffit)
- ⭐️ Mincong Huang (mincong-h)
Changes
Please find the complete list of changes here.
Minor Release 0.10.0
Info
The minor release 0.10.0 focuses on several API improvements.
Please find the complete list of changes here.
The API Docs can be found here
Comitters
🎉 MANY THANKS TO ALL COMMITTERS (AND THEIR PATIENCE)! 🎉
- ⭐️ Amy (@amygithub)
- ⭐️ Andreas Gebhardt (@agebhar1)
- ⭐️ Audun Halland (@audunhalland)
- ⭐️ Daniel Dietrich (@danieldietrich)
- ⭐️ Emmanuel Touzery (@emmanueltouzery)
- ⭐️ Erlend Hamnaberg (@hamnis)
- ⭐️ Florian Stefan (@florian-stefan)
- ⭐️ Grzegorz Gałęzowski (@grzesiek-galezowski)
- ⭐️ Igor Konoplyanko (@cauchypeano)
- ⭐️ J. B. Rainsberger (@jbrains)
- ⭐️ James Lorenzen (@jlorenzen)
- ⭐️ Jia Chen (@grievejia)
- ⭐️ Julien Debon (@Sir4ur0n)
- ⭐️ Nándor Előd Fekete (@nfekete)
- ⭐️ Nataliia Privezentseva (@nataliiaprivezentseva)
- ⭐️ Maciej Górski (@mg6maciej)
- ⭐️ Mathias Düsterhöft (@mduesterhoeft)
- ⭐️ Michał Patejko (@miszasty93)
- ⭐️ Michael Ummels (@ummels)
- ⭐️ Mikołaj Fejzer (@mfejzer)
- ⭐️ Nazarii Bardiuk (@nbardiuk)
- ⭐️ Pap Lőrinc (@paplorinc)
- ⭐️ Pascal Schumacher (@PascalSchumacher)
- ⭐️ Peter Buckley (@dx-pbuckley)
- ⭐️ Robert Erdin (@roberterdin)
- ⭐️ Ruslan Sennov (@ruslansennov)
- ⭐️ Sebastian Zarnekow (@szarnekow)
- ⭐️ Sergey Pereverzov (@serp92)
- ⭐️ Stephen Kestle (@skestle)
- ⭐️ Valery (@valery1707)
- ⭐️ Victor Buldakov (@v1ctor)
Note: A few contributions didn't made it into 0.10.0 because of backward incompatibilities.
Changes
Instead of describing all changes in detail, I will provide a list and show some examples.
Beside new features there were also several (internal) improvements not shown here.
Core/API
- Change (internal): Removed internal interface io.vavr.Lambda which was on top of the (Checked)Function type hierarchy. It was not public.
- Feature: For-comprehension supports List, Option, Future, Try
- Feature: Tuple - append(), concat() and hash()
- Feature: CheckedConsumer, CheckedPredicate and CheckedRunnable enhancements
- Feature: PartialFunction now implements Function1
- Feature: Predicates.not()
- Feature: Value: toJavaArray(IntFunction), toTree(Function, Function)
- Deprecation (for removal): API.Map(Tuple2)
- Deprecation (for removal): API.LinkedMap(Tuple2)
- Deprecation (for removal): API.SortedMap(Tuple2)
- Deprecation (for removal): API.SortedMap(Comparator, Tuple2)
- Deprecation (for removal): API.SortedMap(java.util.Map)
- Deprecation (for removal): Value.toLeft()
- Deprecation (for removal): Value.toRight()
- Deprecation (for removal): Value.toValid()
- Deprecation (for removal): Value.toInvalid()
Collections
- Feature: Traversable: forEachWithIndex, reject(Predicate)
- Feature: Iterator/Stream: fill(int, Object)
- Feature: Map/Multimap: reject(BiPredicate), rejectKeys(Predicate), rejectValues(Predicate), keysIterator(), valuesIterator()
- Feature: Map/Seq: asPartialFunction()
- Feature: Seq.rotateLeft, rotateRight, takeRight, takeRightUntil, takeRightWhile
Concurrent
- Change: Future now uses Executor instead of ExecutorService. The executorService() works as before if Future was initialized with an ExecutorService, otherwise it throws. User executor() instead.
- Change: Future DEFAULT_EXECUTOR: ForkJoinPool.commonPool()
- Feature: Future.await(long timeout, TimeUnit unit)
- Feature: Future.isCancelled()
- Feature (experimental): (Experimental) Future.run(Task), Future.run(Executor, Task)
- Deprecation (for removal): Seq/Map/Set withDefault, withDefaultValue
Controls
- Feature: Either.sequence, Either.sequenceRight
- Feature: Either.traverse, Either.traverseRight
- Feature: Either.filterOrElse
- Feature: Either.toValidation
- Feature: Option.traverse
- Feature: Option.fold
- Feature: Try.traverse
- Feature: Try.onFailure
- Feature: Try.fold
- Feature: Try.toValidation
- Feature: Validation.fromTry
- Feature: Validation.traverse
- Deprecation (for removal): Either.left(), Either.right()
- Deprecation (for removal): Either.LeftProjection, Either.RightProjection
Bugfix Release 0.9.3
Info
The release increases stability and performance.
Please find the complete list of changes here.
The API Docs can be found here
Comitters
🎉 MANY THANKS TO ALL COMMITTERS THAT MADE THIS RELEASE POSSIBLE 🎉
- ⭐️ Andreas Gebhardt (@agebhar1)
- ⭐️ Audun Halland (@audunhalland)
- ⭐️ Daniel Dietrich (@danieldietrich)
- ⭐️ Igor Konoplyanko (@cauchypeano)
- ⭐️ J. B. Rainsberger (@jbrains)
- ⭐️ Jia Chen (@grievejia)
- ⭐️ Nándor Előd Fekete (@nfekete)
- ⭐️ Nataliia Privezentseva (@nataliiaprivezentseva)
- ⭐️ Ruslan Sennov (@ruslansennov)
- ⭐️ Sebastian Zarnekow (@szarnekow)
- ⭐️ Stephen Kestle (@skestle)
- ⭐️ Valery (@valery1707)
Bug fixes
🚨 LinkedHashMap duplicate entries
In Vavr 0.9.2, all LinkedHashMap
factory methods internally did not store keys and values correctly.
Example:
var map = LinkedHashMap(1, "1", 1, "2", 2, "3", 2, "4");
// = 2 (CORRECT)
map.size();
// = LinkedHashSet(1, 1, 2, 2) (WRONG)
// = LinkedHashSet(1, 2) (FIXED)
map.keySet() = LinkedHashSet(1, 1, 2, 2)
// = List("1", "2", "3", "4") (WRONG)
// = List("2", "4") (FIXED)
map.values() = List(1, 2, 3, 4)
Details can be found here.
🚨 TreeSet fell back to natural comparator after removing all elements
// = TreeSet(2, 1)
var set1 = TreeSet.ofAll(Comparator.reverseOrder(), List(1, 1, 2, 2));
// = TreeSet() has now natural comparator (WRONG)
// = TreeSet() keeps reverse order (FIXED)
var set2 = set1.removeAll();
// = TreeSet(1, 2) (WRONG)
// = TreeSet(2, 1) (FIXED)
set2.addAll(List(1, 1, 2, 2));
Details can be found here.
🚨 Stream flatMap memory consumption
Stream.flatMap used an inner class for iteration, with the effect of the result stream holding an unnecessary indirect reference to the head of the source stream, resulting in a "temporary" memory leak.
However, when the reference to the original Stream was garbage-collected, the memory was completely freed.
Details can be found here.
Performance improvements
🏁 Hash code calculation
Internally, we relied on
Objects.hash(T... varargs)
for hashCode calculation. A call
Objects.hash(1, 2, 3)
results in an array creation. In order to prevent that unnecessary instance creation, we added internal methods that preserve our hash semantics.
🏁 Micro-optimizations of collections
We did some micro-optimizations to
CharSeq.ofAll(Iterable)
CharSeq.prependAll(Iterable)
Vector.ofAll(Iterable)
Vector.appendAll(Iterable)
Vector.prependAll(Iterable)
Low-level details can be found here.
New API
🎉 Map additions
We follow the Semantic Versioning scheme. Although this release is a patch release, there are two new methods:
I hope, your OSGi infrastructure does not complain about it.
Jar files
📦 Separate annotation processor jar
We separated annotation vavr-match-processor-<version>.jar
from vavr-match-<version>.jar
.
If you want to create your own pattern matching patterns, you need to include these two dependencies now instead of only vavr-match
.
Documentation
📚 Javadoc improvements
- We clarified that
LinkedHashMap.put(K, V)
andLinkedHashMap.add(T)
have a worst-case linear complexity. This is because equal elements need to be replaced while preserving their position. - Several small improvements and fixes
Other improvements
- Improved interoperability with the GWT compiler
- Improved Eclipse integration for Vavr committers
Bugfix Release 0.9.2
Contributors
Daniel Dietrich
Erlend Hamnaberg
Michael Ummels
Pap Lőrinc
Robert Erdin
Valeriy Vyrva
Changelog
Works fine on JDK 9
Vavr 0.9.2 now works fine on JDK 9. The previous release 0.9.1 had an internal dependency that broke the JDK 9 build - we fixed that.
Note: JDK 9 introduced a type inference bug that may affect Vavr's pattern matching in some cases. Please see JDK-8039214.
Collections
- We fixed the implementation of Multimap.last(). We did not override the default Traversable implementation.
- We fixed a problem with the intersection of ordered collections that are based on RedBlackTree (such as TreeSet).
Concurrent
- We fixed Future.traverse(ExecutorService, Iterable, Function). The ExecutorService was not taken into account.
More fixes...
- Beside the above, we fixed some javadoc typos.
Please find the complete list of changes here.
Bugfix Release 0.9.1
Contributors
Christian Bongiorno
Daniel Dietrich
Emmanuel Touzery
Julien Debon
Nazarii Bardiuk
Pascal Schumacher
Ruslan Sennov
Changelog
Concurrent operations
- We fixed a bug that prevented onFailure actions to be performed when a Future has been cancelled.
- There are known problems with Promise that occur under certain circumstances (see details below). Please note that we did not fix this problem in 0.9.1. We currently work on it in #2093.
The main thread may be blocked forever if we use an operation that blocks on a Future returned by a Promise. We observed this behavior when we used a ForkJoinPool instead of the default CachedThreadPool.
Example:
// we choose a work-stealing thread pool
ExecutorService executor = java.util.concurrent.ForkJoinPool.commonPool();
Future<Object> someFuture = Future.of(executor, () -> longRunningTask());
// the internal Future of a Promise might deadlock the system if we block on that Future
Promise<Object> promise = Promise.make(executor);
someFuture.onComplete(promise::complete);
// the bug only shows up when calling a blocking operation, like get() or isEmpty()
Object result = promise.future().get();
Numeric operations
- Removed the
Traversable.min()
,max()
overloadsTreeSet.min()
andTreeSet.max()
- Made
Traversable.average()
,sum()
andproduct()
more accurate.
TreeSet min()/max()
TreeSet implements SortedSet, which represents distinct elements that are ordered using a specific Comparator.
By default, Traversable.min() and max() calculate the minimum resp. maximum element in linear time O(n) using the natural element order.
However, we used the TreeSet collection characteristic to calculate the min() / max() in constant time O(1).
This was wrong for two reasons:
- The Traversable API spec states that min() and max() are calculated using the natural element order. This has to be the case because of the Liskov substitution principle, see examples below.
- The minimum of any non-empty collection containing double values is Double.NaN if one or more elements are NaN. But the natural Comparator of Double is defined in the way that NaN >= d for every double d.
Example:
// = TreeSet(3, 2, 1)
Set<Integer> ints = TreeSet.of(Comparator.reverseOrder(), 1, 2, 3);
// = 3 (before), = 1 (after)
ints.min();
// = 1 (before), = 3 (after)
ints.max();
// = List(1.0, NaN, 3.0)
List<Integer> doubles = List.of(1.0, Double.NaN, 3.0);
// = 1.0 (before), = NaN (after)
doubles.min();
// = NaN (both ok, before and after this change)
doubles.max();
Traversable average(), sum() and product()
sum() and product() operate on elements of type Number. Now we return a Number according to the input argument or fallback to double.
sum() and average() now internally use an improved summation compensation algorithm that fixes problems that occur in standard Java.
Example:
// = OptionalDouble(0.0) (wrong)
j.u.s.DoubleStream.of(1.0, 10e100, 2.0, -10e100).average()
// = Some(0.75) (correct)
List.of(1.0, 10e100, 2.0, -10e100).average()
Missing methods
We added
Either.sequence(Iterable<? extends Either<? extends L, ? extends R>>)
Either.sequenceRight(Iterable<? extends Either<? extends L, ? extends R>>)
Examples:
// = Right(List(all, right)) of type Either<Seq<Integer>, Seq<String>>
Either.sequence(List.of(Either.right("all"), Either.right("right")));
// = Left(List(1, 2)) of type Either<Seq<Integer>, Seq<String>>
Either.sequence(List.of(Either.left(1), Either.left(2), Either.right("ok")));
// = Right(List(all, right)) of type Either<Integer, Seq<String>>
Either.sequenceRight(List.of(Either.right("all"), Either.right("right")));
// = Left(1) of type Either<Integer, Seq<String>>
Either.sequenceRight(List.of(Either.left(1), Either.left(2), Either.right("ok")));
Type narrowing
We changed the generic bounds of these method arguments:
Function0<R>.narrow(Function0<? extends R>)
(before:narrow(Supplier<? extends R>)
)Function1<T1, R> Function1.narrow(Function1<? super T1, ? extends R>)
(before:narrow(Function<? super T1, ? extends R>)
)Function2<T1, T2, R> Function2.narrow(Function2<? super T1, ? super T2, ? extends R>)
(before:narrow(BiFunction<? super T1, ? super T2, ? extends R>)
)
Background: Java is not able to do the following type assignment:
M<? extends T> m = ...;
M<T> narrowed = m; // does not work but it is correct for immutable objects.
Therefore almost all Vavr types have narrow
methods.
M<? extends T> m = ...;
M<T> narrowed = M.narrow(m); // works as expected
GWT compatibility fixes
The following methods were annotated with @GwtIncompatible
:
Predicates#instanceOf(Class)
asJava()
,asJava(Consumer)
,asJavaMutable()
,asJavaMutable(Consumer)
ofio.vavr.collection.Seq
and all its subtypes,
namelyIndexedSeq
,LinearSeq
,Array
,CharSeq
,List
,Queue
,Stream
andVector
Documentation
We added more examples and improved the readability of the Javadoc:
Thanks to Stuart Marks, he was so kind to initiate an issue in order to improve the default Javadoc style.
You find the Vavr 0.9.1 API specification here.
More fixes...
- We removed internal memoization of sortBy() in order to fix an issue with lazy collections that have infinite size
- We optimized collection conversion
- We fixed the generics of Multimap builders
- We improved Traversable.reduceLeft
- We improved Iterator.dropWhile and slideBy
Please find the complete list of changes here.