An open API service indexing awesome lists of open source software.

https://github.com/siy/pragmatica-lite

Modern Functional Programming for Java 25
https://github.com/siy/pragmatica-lite

Last synced: 5 months ago
JSON representation

Modern Functional Programming for Java 25

Awesome Lists containing this project

README

          

# Pragmatica Lite

![License](https://img.shields.io/badge/license-Apache%202-blue.svg)
![Java](https://img.shields.io/badge/Java-25-orange.svg)
![Maven Central](https://img.shields.io/badge/Maven-0.9.7-blue.svg)

## Modern Functional Programming for Java 25

Pragmatica Lite brings the power of functional programming to Java with zero-dependency monadic types that eliminate null pointer exceptions, unchecked exceptions, and callback hell. Built on Java 25's latest features including sealed interfaces and pattern matching.

## Why Pragmatica Lite?

**Without Pragmatica:**
```java
// Traditional Java - prone to NPE and unhandled exceptions
public User getUser(String id) throws UserNotFoundException, DatabaseException {
User user = database.findUser(id); // Can throw exception
if (user == null) { // NPE risk
throw new UserNotFoundException(id);
}
return user;
}
```

**With Pragmatica:**
```java
// Clean, safe, composable
public Result getUser(String id) {
return database.findUser(id)
.filter(user -> user.isActive())
.map(this::enrichUserData)
.recover(DatabaseError.class, this::handleDatabaseError);
}
```

## Core Features

### Eliminate Null Pointer Exceptions
```java
Option name = Option.of(user.getName())
.map(String::toUpperCase)
.filter(n -> n.length() > 2)
.orElse("Anonymous");
```

### Safe Error Handling Without Exceptions
```java
Result divide(int a, int b) {
return b == 0
? Result.err(new MathError("Division by zero"))
: Result.ok(a / b);
}

// Chain operations safely
Result result = divide(10, 2)
.map(x -> x * 2)
.map(Object::toString)
.recover(MathError.class, err -> "Error: " + err.message());
```

### Asynchronous Programming Made Simple
```java
Promise getUserProfile(String userId) {
return fetchUser(userId)
.flatMap(user -> fetchPreferences(user.id()).map(prefs -> new UserProfile(user, prefs)))
.onSuccess(profile -> cache.store(profile))
.onFailure(error -> logger.error("Failed to load profile", error));
}
```

### Process Collections Safely
```java
List> userResults = userIds.stream()
.map(this::fetchUser)
.toList();

// Collect all successes, fail if any operation failed
Result> allUsers = Result.allOf(userResults);

// Or collect only successful operations
List validUsers = Result.collectSuccesses(userResults);
```

## Modern Java 25 Features

Pragmatica Lite leverages cutting-edge Java 25 features:

- **Sealed Interfaces**: Type-safe Result and Option hierarchies
- **Pattern Matching**: Elegant switch expressions for monadic types
- **Records**: Immutable data structures throughout

### Maven Configuration

Pragmatica Lite is available on Maven Central. Simply add the dependency to your `pom.xml`:

```xml

org.pragmatica-lite
core
0.9.7

```

For Gradle users:

```gradle
implementation 'org.pragmatica-lite:core:0.9.7'
```

### Your First Pragmatica Application

```java
import org.pragmatica.lang.*;

public class Example {
// Safe division that never throws
public static Result safeDivide(double a, double b) {
return b == 0.0
? MathError.divisionByZero().result()
: Result.ok(a / b);
}

// Chaining operations
static void main(String[] args) {
safeDivide(10.0, 2.0)
.map(result -> result * 2) // Transform success value
.fold(
error -> "Error: " + error.message(),
success -> "Result: " + success
);
}
}
```

## API Overview

### Result<T> - Railway-Oriented Programming
Handle success and failure without exceptions:

```java
Result result = processData()
.map(String::trim)
.filter(s -> !s.isEmpty())
.recover(ValidationError.class, err -> "default");
```

### Option<T> - Null Safety
Eliminate null pointer exceptions:

```java
Option user = findUser(id)
.filter(User::isActive)
.map(User::getProfile);
```

### Promise<T> - Async Operations
Composable asynchronous programming:

```java
Promise response = httpClient.get(url)
.map(Response::body)
.timeout(Duration.ofSeconds(5))
.onFailure(err -> logger.error("Request failed", err));
```

## Design Principles

- **Zero Dependencies**: No external libraries required
- **Type Safety**: Leverage Java's type system for correctness
- **Performance**: Minimal overhead, allocation-free operations
- **Composability**: Chain operations naturally
- **Modern Java**: Built for Java 25 and beyond

## Examples and Documentation

Explore comprehensive examples in the [examples](examples) directory:
- Asynchronous data processing with Promise
- Error handling patterns with Result
- Null-safe operations with Option
- Real-world application patterns

## Module Structure

| Module | Description |
|--------|-------------|
| **core** | Core monadic types: Result, Option, Promise |
| **examples** | Sample applications and usage patterns |

### Integration Modules

| Category | Module | Description | Docs |
|----------|--------|-------------|------|
| **Config** | [toml](integrations/config/toml) | Zero-dependency TOML parser | [README](integrations/config/toml/README.md) |
| **Consensus** | [consensus](integrations/consensus) | Rabia consensus protocol (CFT) | [README](integrations/consensus/README.md) |
| **Database** | [jdbc](integrations/db/jdbc) | Promise-based JDBC with HikariCP | [README](integrations/db/jdbc/README.md) |
| | [jpa](integrations/db/jpa) | JPA/Hibernate integration | [README](integrations/db/jpa/README.md) |
| | [r2dbc](integrations/db/r2dbc) | Reactive database access | [README](integrations/db/r2dbc/README.md) |
| | [jooq](integrations/db/jooq) | Promise-based JOOQ with JDBC | — |
| | [jooq-r2dbc](integrations/db/jooq-r2dbc) | Promise-based JOOQ with R2DBC | [README](integrations/db/jooq-r2dbc/README.md) |
| **Distributed** | [dht](integrations/dht) | Distributed Hash Table | [README](integrations/dht/README.md) |
| **JSON** | [jackson](integrations/json/jackson) | Jackson 3.0 serialization | [README](integrations/json/jackson/README.md) |
| **Messaging** | [messaging](integrations/messaging) | Message queue abstractions | [README](integrations/messaging/README.md) |
| **Metrics** | [micrometer](integrations/metrics/micrometer) | Micrometer observability | [README](integrations/metrics/micrometer/README.md) |
| **Network** | [http-client](integrations/net/http-client) | Promise-based HTTP client | [README](integrations/net/http-client/README.md) |
| | [tcp](integrations/net/tcp) | TCP networking utilities | [README](integrations/net/tcp/README.md) |
| | [dns](integrations/net/dns) | DNS client | [README](integrations/net/dns/README.md) |
| **Serialization** | [serialization](integrations/serialization) | Binary serialization (Fury, Kryo) | [README](integrations/serialization/README.md) |

## Integrations

### Jackson JSON (3.0.0)

Serialize and deserialize Result, Option, and Promise types:

```xml

org.pragmatica-lite
jackson
0.9.7

```

```java
var mapper = JsonMapper.jsonMapper()
.withPragmaticaTypes()
.build();

// Result serialization
Result result = fetchUser(id);
mapper.writeAsString(result) // Result
.onSuccess(json -> sendResponse(json));

// Type-safe deserialization
mapper.readString(json, new TypeToken>() {})
.onSuccess(users -> processUsers(users));
```

### JPA Database Integration

Promise-based JPA operations with typed errors:

```xml

org.pragmatica-lite
jpa
0.9.7

```

```java
var ops = JpaOperations.jpaOperations(entityManager);

// Transactional operations
Promise result = Transactional.withTransaction(
entityManager,
JpaError::fromException,
tx -> ops.persist(newUser)
.flatMap(saved -> ops.flush().map(_ -> saved))
);

// Typed errors: EntityNotFound, OptimisticLock, DatabaseFailure, etc.
result.onFailure(error -> switch (error) {
case JpaError.EntityNotFound _ -> handleNotFound();
case JpaError.OptimisticLock lock -> handleConflict(lock.entityType());
case JpaError.DatabaseFailure db -> handleDatabaseError(db.cause());
default -> handleUnexpected(error);
});
```

### Micrometer Metrics

Monitor Result, Option, and Promise operations:

```xml

org.pragmatica-lite
micrometer
0.9.7

```

```java
// Wrap operations with metrics
var wrappedOperation = ResultMetrics.timed(
registry,
"user.fetch",
Tags.of("service", "user-service"),
() -> fetchUser(userId)
);

// Automatic success/failure tracking
Promise monitored = PromiseMetrics.counted(
registry,
"api.call",
Tags.of("endpoint", "/users"),
apiClient.fetchData()
);
```

## Contributing

We welcome contributions! Please feel free to submit pull requests, report issues, or suggest improvements.

### Development Requirements
- Java 25 or higher
- Maven 3.9+

## Support

If you find this useful, consider [sponsoring](https://github.com/sponsors/siy).

## License

Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.