Arrow 1.2.3 release
We are happy to announce the availability of version 1.2.3 of the Arrow collection of libraries.
According to our plan, this is the last non-bugfix release of the 1.x series.
From now on, our main
branch targets Arrow 2.0, which should be the next major release.
We are incredibly thankful to the many people that have contributed to this release, bringing new ideas and quite some code.
Version 1.2.3 of arrow-core
changed the behavior of Raise
computations returning
functions or sequences. This change restricted some useful usages,
so the team has decided to roll it back and keep the 1.2.1 behavior.
New features
A version number like 1.2.3 sounds like a small bugfix release, but this is far from truth in this case: this release is full of new modules to help you be productive when writing Kotlin.
Improved focus on Compose
Arrow provides building blocks relevant to many projects using Kotlin. A large part of our community is doing frontend work, and during the latest months, the team has been trying to understand their needs, in order to make Arrow a relevant tool in that space.
From that journey, we have put together a new documentation page highlighting
different ways in which Arrow may be useful in your Compose application.
There is also a new arrow-optics-compose
module
that includes utilities to work with immutable data inside a MutableState
or MutableStateFlow
.
We are eager to hear more use cases or needs where Arrow may help the lives
of Kotlin developers. Feel free to drop by the #arrow
channel in the Kotlin Slack,
or open an issue or discussion in our repository.
Non-suspend
resource management
Resource safety in Arrow
has been traditionally tied to the use of coroutines and suspend
functions.
This is the right choice for Kotlin-first libraries, like Ktor or Koin, but many
libraries still come from a Java background where no such feature exists.
Beginning with this version, we provide two "variations" of resource management:
Resource
, from thearrow-fx-coroutines
module, is based onsuspend
and ensures the desired behavior alongside coroutines (including cancellation).AutoClose
, from the newarrow-autoclose
module, provides almost the same API asResource
, but without thesuspend
requirement.
Forward compatible Eval
One of our goals is to make the transition to 2.0 as smooth as possible. You can already migrate to the new APIs by using Arrow 1.2.3, and then ensuring that you get no deprecation warnings.
During this process, we were made aware that
there was no clear story for the migration of Eval
. On the other hand, the use cases are very narrow.
The decision was to create a new arrow-eval
module,
present since this release, and mark the one from arrow-core
point the new module,
instead of entirely removing this functionality from Arrow.
Collectors
The new arrow-collectors
module
allows composing operations over sequences of values
(lists, flows, sequences) while ensuring that the sequence is traversed only once.
This property is especially relevant when building the sequence is expensive, or simply
cannot be reproduced, like a stream of data from a database or a flow of actions.
Improved features
Several features in the library have been improved, to ensure that Arrow covers a variety of use cases.
Lenses for sealed classes
This was once of the older feature requests still in our issue tracker, which is now closed thanks to a wonderful contribution!
From now on, the Optics KSP plug-in can generate lenses for sealed hierarchies, given that the field lives in the common parent. For example, the following code
@optics sealed interface User {
val name: String
data class Person(override val name: String, val age: Int): User
data class Company(override val name: String, val vat: VATNumber): User
}
generates from this version on both prisms for each choice, and a lens for name
.
Higher-arity functions
We have traditionally been reluctant to add variations of zip
with more than
10 parameters, because we felt that the narrow use cases did not balance out
the increase in binary size. Since this release Arrow provides those functions
in a new arrow-core-high-arity
module.
More accumulating functions for Raise
Typed errors
provide two essential ways to accumulate errors: zipOrAccumulate
and mapOrAccumulate
. Those correspond
to accumulating over a fixed number of computations of different types, or
accumulating over an unknown quantity of computations with the same type.
The mapOrAccumulate
function always returns a new list. In some cases, you
don't really care about this result, just about the iteration behavior.
This is similar to the different between map
and forEach
in the standard
library. From there Arrow takes the name of the new function: forEachAccumulating
.
One potential use case is performing validation over elements of a list, but keeping the values intact.
people.forEachAccumulating { person ->
ensure(person.age >= 0) { InvalidAge(person.name) }
}
Better memoization
MemoizedDeepRecursiveFunction
is a powerful tool to express recursive algorithms without worries over stack overflow or recomputation.
However, there was a lack of control over how memoized values were stored or evicted, which made the
type less useful than intended.
From this release on, there are new overloads to support custom memoization policies.
Furthermore, the new arrow-cache4k
module
provides integration with the excellent
cache4k library.
More integrations
Although not part of this release, we would like to highlight that Akkurate, which provides a wonderful DSL for validation over data, has released an integration module for Arrow. This adds to the rest of integrations and shows the collaborative spirit of the Kotlin community.