https://github.com/dzikoysk/expressible
Utility library dedicated for functional & non-functional codebases to simplify modelling of success and failure responses for Java/Kotlin 🔀
https://github.com/dzikoysk/expressible
coroutines functional-programming hacktoberfest java kotlin kotlin-coroutines option panda panda-lang result utility
Last synced: 7 months ago
JSON representation
Utility library dedicated for functional & non-functional codebases to simplify modelling of success and failure responses for Java/Kotlin 🔀
- Host: GitHub
- URL: https://github.com/dzikoysk/expressible
- Owner: dzikoysk
- License: apache-2.0
- Created: 2021-07-15T23:35:29.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-07-29T23:59:18.000Z (about 1 year ago)
- Last Synced: 2025-03-01T05:41:25.911Z (8 months ago)
- Topics: coroutines, functional-programming, hacktoberfest, java, kotlin, kotlin-coroutines, option, panda, panda-lang, result, utility
- Language: Java
- Homepage:
- Size: 391 KB
- Stars: 31
- Watchers: 2
- Forks: 3
- Open Issues: 6
-
Metadata Files:
- Readme: .github/README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Expressible [](https://github.com/panda-lang/expressible/actions/workflows/gradle.yml) [](https://codecov.io/gh/panda-lang/expressible) 
Dependency free utility library for Java & Kotlin, dedicated for functional codebases that require enhanced response handling.
Express yourself with inspired by Rust, Kotlin and Vavr wrappers, to provide better API using this tiny library.
Supported wrappers (in `panda.std.*` package):
| Features | Description |
|----------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| `Result` | solve error handling gracefully, get rid of exception based side-effects |
| `Option` | enhanced alternative to standard `Optional` |
| `Lazy` | lazy values & runners |
| `Completable`
with `Publisher` & `Subscriber` | synchronized alternative to `CompletableFuture` |
| `Reference`,
`MutableReference`,
`Computed` | Simple reactive containers |
| `Mono`,
`Pair`,
`Triple`,
`Quad` | generic wrappers for set of values |
| Throwing functions, runnables, suppliers and consumers | set of functional interfaces with support for exception signatures |
| Tri and Quad consumers, functions and predicates | additional functional interfaces |
| `PandaStream` | `Stream` wrapper with support for features provided by `expresible` library |By default, expressible exposes non-terminating methods,
so you can freely divide functions into smaller pieces and move from non-functional codebases without having a heart attack.
```kotlin
dependencies {
implementation("org.panda-lang:expressible:1.3.6") // Core library
implementation("org.panda-lang:expressible-kt:1.3.6") // Kotlin extensions
testImplementation("org.panda-lang:expressible-junit:1.3.6") // JUnit extensions
}
```### Examples
Suggested snippets show only a small use-cases for the available api.
You're not forced to use this library this way, so you may need to find your style in expressing your thoughts.
Adopting functional approach requires time and to simplify this process it's easier to slowly introduce new elements based on simple concepts.#### Result
Rather than using `Exception` based error handling, return meaningful errors and interact with api responses gracefully.
Following functional programming patterns make sure your methods don't contain side effects and unexpected exit points.```kotlin
class UserEndpoint {
// You can use fully functional approach
fun createUser(request: HttpRequest, response: HttpResponse) =
userFacade.createUsername(request.param("username"))
.peek { user -> response.respondWithJsonDto(user) }
.onError { error -> ErrorReposne(BAD_REQUEST, error) }
}class UserFacade {
// You can start adoption in a regular, non-functional codebases
fun createUser(username: String): Result {
if (userRepository.findUserByName(username).isPresent()) {
return error("User $username already exists")
}
return ok(userRepository.createUser(username))
}
}internal class UserFacadeTest : UserSpec {
// JUnit support
@Test
fun `should create user with a valid username` () {
// given: a valid username
val username = 'onlypanda'
// when: user is created with the following name
val user = userFacade.createUser(username)
// then: user has been created
assertOk(username, user.map(User::getUsername))
}
}
```#### Option
Similar usage to `Optional` type provided by Java:```java
Option withValue = Option.of("Value");
Option empty = Option.empty();
```#### Lazy
```java
Lazy completed = new Lazy<>("Value");
Lazy lazy = new Lazy<>(() -> "Value");
Lazy initialize = Lazy.ofRunnable(() -> "Called just once);String value = completed.get();
```#### Completable
```java
Completable completable = Completable.create();completable
.thenApply(value -> parseBoolean(value))
.then(value -> System.out.println(value));completable.complete("true");
```#### Reactive
```java
Reference a = reference(1);
MutableReference b = mutableReference(2);
Computed result = computed(dependencies(a, b), () -> a.get() + b.get());result.subscribe(value -> System.out.println(value));
b.update(3); // prints "4"
```#### Panda Stream
```java
PandaStream empty = PandaStream.empty();
PandaStream standard = PandaStream.of(new ArrayList<>().stream());
```### Used by
* [Panda Organization](https://github.com/panda-lang) ([Panda](https://github.com/panda-lang/panda), [Hub](https://github.com/panda-lang/hub), [Light](https://github.com/panda-lang))
* [Reposilite](https://github.com/dzikoysk/reposilite)
* Libraries like [CDN](https://github.com/dzikoysk/cdn), [Dependency-Injector](https://github.com/dzikoysk/dependency-injector)
* [FunnyGuilds Organization](https://github.com/FunnyGuilds) ([FunnyGuilds](https://github.com/FunnyGuilds/FunnyGuilds), [FunnyCommands](https://github.com/FunnyGuilds/FunnyCommands))
* Private projects and API consumers of the given libraries