Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare release notes for 1.2.3 #269

Merged
merged 7 commits into from
Feb 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions content/blog/2024-02-28-arrow-1-2-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
title: Arrow 1.2.3 release
category: articles
tags: [core, articles]
---

# 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.

## 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](/learn/immutable-data/lens/#integration-with-compose)
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](https://github.com/arrow-kt/arrow).

### Non-`suspend` resource management

[Resource safety](/learn/coroutines/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 the `arrow-fx-coroutines` module, is based on `suspend`
and ensures the desired behavior alongside coroutines (including cancellation).
- `AutoClose`, from the new `arrow-autoclose` module, provides almost the
same API as `Resource`, but without the `suspend` requirement.

### Forward compatible `Eval`

One of our goals is to make the transition to 2.0 as smooth as possible.
You can [already migrate](/learn/quickstart/migration/)
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](https://github.com/arrow-kt/arrow/issues/3039) 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](/learn/collections-functions/eval/),
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](/learn/collections-functions/collectors/)
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](https://github.com/arrow-kt/arrow/issues/2829)
still in our issue tracker, which is now closed thanks to a wonderful
[contribution](https://github.com/arrow-kt/arrow/pull/3359)!

From now on, the Optics KSP plug-in can generate
[lenses for sealed hierarchies](/learn/immutable-data/lens/#sealed-class-hierarchies),
given that the field lives in the common parent. For example, the following code

```kotlin
@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](/learn/typed-errors/working-with-typed-errors/)
provide two essential ways to [accumulate errors](/learn/typed-errors/working-with-typed-errors/#accumulating-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.

```kotlin
people.forEachAccumulating { person ->
ensure(person.age >= 0) { InvalidAge(person.name) }
}
```

### Better memoization

[`MemoizedDeepRecursiveFunction`](/learn/collections-functions/recursive/#memoized-recursive-functions)
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](/learn/collections-functions/recursive/#memoization-takes-memory)
provides integration with the excellent
[cache4k](https://github.com/ReactiveCircus/cache4k) library.

## More integrations

Although not part of this release, we would like to highlight that
[Akkurate](https://akkurate.dev), which provides a wonderful DSL for validation over data,
has released an [integration module for Arrow](https://akkurate.dev/docs/arrow-integration.html).
This adds to the [rest of integrations](/learn/integrations/)
and shows the collaborative spirit of the Kotlin community.