It started with a simple question: what can I do with the new features shipping in Java 25?
I have always loved functional programming. The way it pushes you to think in terms of transformations, immutability, and composition just makes code easier to reason about. So when modern Java started shipping features that genuinely enable functional idioms — record patterns, Stream Gatherers, sealed types, module import declarations — I saw an opportunity I could not ignore: take the principles I care about and express them using the best of what the language now offers.
I wanted a playground — something concrete enough to exercise those ideas in practice. I was not planning to build a library. I was planning to experiment for a weekend.
A few weeks later I had Option<T>, Result<V,E>, Try<V>, Validated<E,A>, Tuple2,
Tuple3, Tuple4, Lazy<T>, zip combinators, checked functional interfaces, and a test suite
with more than 500 tests. At some point it stopped being a playground and became something I
was actually reaching for in my personal projects. That felt like a signal worth following —
if it was useful to me it might be useful to others.
So here we are. dmx-fun is a small, opinionated functional programming library for Java,
built to be read and understood, not just consumed. And this post is about where it is going.
The three milestones ahead
0.0.13 — Completeness and documentation (due April 2026)
The immediate priority is making the existing API feel complete and making it easy to learn.
On the API side:
Either<L,R>— a proper disjoint union type for representing one of two possible values.NonEmptyList<T>— a list guaranteed to have at least one element, useful in validation pipelines.recoverandrecoverWithonTry— ergonomic fallback combinators.orElse(Container)onOptionandResult— fallback chaining between containers.- Custom AssertJ assertions for all
dmx-funtypes, so tests read as clearly as the production code they verify. CollectorsforValidated—partitionandsequenceas standard stream collectors.- Structured Concurrency adapters — bridging virtual threads and
Try/Result. - Jackson module — first-class JSON serialization for all library types.
On the documentation side, this milestone is the biggest investment yet. A full Developer Guide is being written, with dedicated pages for every type in the library:
Option<T>— representing the absence of a value without nullResult<V,E>— typed error handling without exceptionsTry<V>— wrapping computations that may throwValidated<E,A>— error-accumulating validationTuple2,Tuple3,Tuple4— immutable product typesLazy<T>— deferred, memoized evaluation- Checked functional interfaces and higher-arity functions
- Cross-type composition patterns
The goal is that someone new to functional programming in Java can open the guide and understand not just how to use each type but why it exists and when to reach for it.
0.0.14 — Spring integration (due May 2026)
The single most-requested integration from my own projects: making Result<V,E> and Try<V>
work naturally with Spring’s transaction management.
The plan is a new subproject, dmx-fun-spring, that provides:
- Programmatic transaction support — utilities for running
Result- andTry-returning operations inside a transaction boundary, with automatic rollback onErrorFailure. - Declarative AOP support —
@TransactionalResultand@TransactionalTryannotations that work like Spring’s own@Transactionalbut are aware of the functional return types.
The idea is simple: if a method returns Result.err(...), the transaction should roll back —
just as it would for an unchecked exception. Today you have to wire that manually. After 0.0.14
you should not have to think about it.
0.0.15 — Quarkus integration (due May 2026)
Everything in dmx-fun-spring has a Quarkus equivalent. The dmx-fun-quarkus subproject will
provide the same two layers:
- Programmatic transaction support for
ResultandTryusing Quarkus’sQuarkusTransactionAPI. - CDI interceptor-based declarative support via
@TransactionalResultand@TransactionalTry, built on top of Quarkus’s interceptor model instead of Spring AOP.
Having both integrations in the same repository means the contracts stay aligned and the experience is consistent regardless of which framework you are using.
The bigger picture
These three milestones are not just a feature list — they represent a shift in what dmx-fun
is trying to be.
Until now it has been a core library: types, combinators, and tests. Starting with 0.0.13 it becomes something you can learn from. Starting with 0.0.14 it becomes something you can drop into a real Spring or Quarkus project without friction.
The library started as an experiment. The roadmap is about making it robust enough to be trusted in production — not by abandoning the simplicity that made it useful to begin with, but by extending it carefully, one well-scoped milestone at a time.
Getting involved
The library, all open issues, and the milestone tracker are public on GitHub. If any of this sounds useful — or if you have ideas for what should come in 0.0.16 and beyond — issues and pull requests are very welcome.
// Gradle (Kotlin DSL)implementation("codes.domix:fun:0.0.13")<!-- Maven --><dependency> <groupId>codes.domix</groupId> <artifactId>fun</artifactId> <version>0.0.13</version></dependency>