Skip to content

aether-framework-labs/aether-fp

Aether FP

Functional programming primitives for Java 21+.

License: MIT Java 21+ CI Coverage

Overview

Aether FP provides type-safe, immutable functional programming primitives for Java 21 and beyond. It offers algebraic sum types and deferred computation containers that leverage modern Java features like sealed interfaces, pattern matching, and records.

All types are immutable and thread-safe, enforce a strict null prohibition policy, and compose naturally through map, flatMap, and fold operations. The library has zero runtime dependencies beyond JetBrains Annotations.

Note: Version < 1.0.0 indicates Aether Labs / experimental status with production-grade quality standards.

πŸ“‹ Table of Contents

πŸš€ Quick Start

1. Add the dependency

<dependency>
    <groupId>de.splatgames.aether.fp.labs</groupId>
    <artifactId>aether-fp-core</artifactId>
    <version>0.1.0</version>
</dependency>
Gradle (Groovy / Kotlin)
// Groovy
implementation 'de.splatgames.aether.fp.labs:aether-fp-core:0.1.0'
// Kotlin
implementation("de.splatgames.aether.fp.labs:aether-fp-core:0.1.0")

2. Use functional types

import de.splatgames.aether.fp.types.Either;
import de.splatgames.aether.fp.types.Result;
import de.splatgames.aether.fp.types.Lazy;

// Either: right-biased sum type
Either<String, Integer> parsed = Either.right("42")
    .map(Integer::parseInt);

// Result: success-biased operation outcome
Result<User, String> user = findUser(id)
    .map(User::activate)
    .recover(err -> User.guest());

// Lazy: thread-safe memoized computation
Lazy<Config> config = Lazy.of(() -> loadExpensiveConfig());
// Computed only on first access, cached forever

πŸ“¦ Installation

Maven

<dependency>
    <groupId>de.splatgames.aether.fp.labs</groupId>
    <artifactId>aether-fp-core</artifactId>
    <version>0.1.0</version>
</dependency>
Gradle (Groovy / Kotlin)
// Groovy
implementation 'de.splatgames.aether.fp.labs:aether-fp-core:0.1.0'
// Kotlin
implementation("de.splatgames.aether.fp.labs:aether-fp-core:0.1.0")

Using the BOM

The Bill of Materials ensures consistent versions across all Aether FP modules.

Maven

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>de.splatgames.aether.fp.labs</groupId>
            <artifactId>aether-fp-bom</artifactId>
            <version>0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- No version needed -->
    <dependency>
        <groupId>de.splatgames.aether.fp.labs</groupId>
        <artifactId>aether-fp-core</artifactId>
    </dependency>
</dependencies>
Gradle (Groovy / Kotlin)
// Groovy
dependencies {
    implementation platform('de.splatgames.aether.fp.labs:aether-fp-bom:0.1.0')
    implementation 'de.splatgames.aether.fp.labs:aether-fp-core'
}
// Kotlin
dependencies {
    implementation(platform("de.splatgames.aether.fp.labs:aether-fp-bom:0.1.0"))
    implementation("de.splatgames.aether.fp.labs:aether-fp-core")
}

🧩 Core Types

Either<L, R> β€” Right-Biased Sum Type

A discriminated union representing exactly one of two possible values. By convention, left represents the error/alternative case and right represents the success/primary case.

Either<String, Integer> success = Either.right(42);
Either<String, Integer> failure = Either.left("not found");

// Right-biased map
Either<String, String> mapped = success.map(n -> "value: " + n);
// mapped = Right[value: 42]

// Chain with flatMap
Either<String, Integer> parsed = Either.<String, String>right("123")
    .flatMap(s -> {
        try {
            return Either.right(Integer.parseInt(s));
        } catch (NumberFormatException e) {
            return Either.left("invalid number: " + s);
        }
    });

// Exhaustive pattern matching
String result = success.fold(
    error -> "Error: " + error,
    value -> "Success: " + value
);

Key operations: map, flatMap, mapLeft, fold, swap, getOrElse, getOrElseGet, getOrElseThrow, ifLeft, ifRight

Result<T, E> β€” Success-Biased Operation Outcome

Purpose-built for modeling operations that may succeed or fail. Provides dedicated recovery operations and converts to Either for interoperability.

Result<Integer, String> success = Result.success(42);
Result<Integer, String> failure = Result.failure("not found");

// Success-biased composition
Result<String, String> mapped = success.map(n -> "value: " + n);

// Error recovery
Result<Integer, String> recovered = failure.recover(err -> 0);

// Convert to Either
Either<String, Integer> either = success.toEither();

Key operations: map, flatMap, mapError, fold, recover, recoverWith, getOrElse, getOrElseGet, getOrElseThrow, toEither, ifSuccess, ifFailure

Lazy<T> β€” Thread-Safe Memoized Computation

Wraps a Supplier and defers evaluation until the value is first accessed. Once evaluated, the result is cached permanently. Thread-safe via double-checked locking.

Lazy<String> lazy = Lazy.of(() -> expensiveComputation());
// lazy.isEvaluated() == false

String value = lazy.get(); // evaluates once
String same = lazy.get();  // returns cached value

// Compose lazily β€” no evaluation
Lazy<Integer> length = lazy.map(String::length);

Key operations: get, map, flatMap, isEvaluated, ifEvaluated, toOptional

πŸ“¦ Modules

Module Description
aether-fp-core Core FP types: Either, Result, Lazy
aether-fp-bom Bill of Materials for version management

πŸ“– Documentation

Comprehensive documentation is available in the docs/ directory:

  • πŸ“˜ Getting Started β€” Installation and quick start guide
  • πŸ’‘ Concepts β€” Sum types, null safety, biased composition, lazy evaluation, thread safety
  • πŸŽ“ Tutorials β€” Working with Either, Result, Lazy, and combining types
  • πŸ”§ How-To Guides β€” Replace exceptions, replace null checks, chain operations, recover from errors
  • πŸ“ Examples β€” Validation pipelines, service layer patterns, configuration loading
  • πŸ“š Appendix β€” Glossary and quick reference

πŸ”¨ Building from Source

Prerequisites:

  • Java 21+
  • Maven 3.9.5+
# Build (skip tests)
mvn clean install -DskipTests

# Build with tests
mvn clean install

# QA profile (JaCoCo, SpotBugs, Checkstyle, OWASP, CycloneDX)
mvn verify -Pqa

# Integration tests
mvn verify -Pit

🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Please note that this project is released with a Code of Conduct. By participating in this project you agree to abide by its terms.

πŸ”’ Security

For security concerns, please see our Security Policy.

Do not report security vulnerabilities in public issues. See the security policy for responsible disclosure instructions.

πŸ“œ License

MIT β€” see LICENSE.

Copyright (c) 2026 Splatgames.de Software and Contributors

About

Aether FP is a library that brings functional programming types to Java.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages