Skip to content

Smallibs/hpas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HiPeAS

Codacy Badge Coverage Status stable Maven Central

Functional paradigm deeply drives the design with a taste of OO for encapsulation and chaining methods which mimics infix operators like Haskell monad function >>=.

In addition, with version 21 of Java an Async/Await DSL like is available.

Since such ADT provides traditional map, flapmap etc. functions for a DSL perspective are also given in order to increase the code readability.

A taste of HiPeAS

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());
Promise<String> helloWorldPromise = executor.async(() -> "Hello").and(s -> s + " world!");

HiPeAS overview

Synchronous data types

Basically well known MayBe and Try are available for this purpose. Theses ADT are also the basis for the asynchronous part of this library.

Asynchronous computational model

Executors

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());

async

In Executor <T> async :: (() -> T) → Promise<T>

Promise<Integer> integerPromise = executor.async(() -> 1);

await

In ExecutorHelper <T> await :: (Promise<T>, Duration) → Try<T>

Try<Integer> result = ExecutorHelper.await(integerPromise, Duration.TWO_SECONDS);

Promise

and or map

In Promise<T> <R> map :: (T → R) → Promise<R>

In Promise<T> <R> and :: (T → R) → Promise<R>

integerPromise.map(i -> i + 1);
integerPromise.and(i -> i + 1);

then or flatmap

In Promise<T> <R> flatmap :: (T → Promise<R>) → Promise<R>

In Promise<T> <R> then :: (T → Promise<R>) → Promise<R>

integerPromise.flatmap(i -> executor.async(() -> i + 1));
integerPromise.then(i -> executor.async(() -> i + 1));

Back to the Future

In Promise<T> getFuture :: () → Future<T>

integerPromise.getFuture();

Conclude on success

In Promise<T> onSuccess :: (T → void) → Promise<T>

integerPromise.onSuccess(i -> System.println(i))

Conclude on failure

In Promise<T> onFailure :: (Throwable → void) → Promise<T>

integerPromise.onFailure(t -> t.printStackTrace(System.err))

Conclude on complete

In Promise<T> onComplete :: (Try<T> → void) → Promise<T>

integerPromise.onComplete(t -> t.fold(integerPromise::onSuccess, integerPromise::onFailure));

Async Await DSL

Now we can use async/await mechanism using Loom virtual thread. We can now await for a promise implying an asynchronous mechanism based on thread parking if it's a virtual thread or a blocking procedure for system thread.

var executor = ExecutorHelper.create(Executors.newVirtualThreadPerTaskExecutor());

var aLongAddition = executor.async(() -> {
    var firstInteger = executor.async(() -> /* do something */ 2);
    Thread.sleep(3000); // Current thread do nothing during 3 seconds
    var firstInteger = executor.async(() -> /* do something else */ 5);

    return firstInteger.await() + secondInteger.await(); // Await force virtual thread parking 
}).await(); // System thread waiting for the result

Functor, Applicative and Monad

In addition monadic approach is available for each ADT. As usual Monad ihnerits Applicative which inherits Functor.

Functor

In PromiseHelper functor<T> :: Promise<T> → Functor<T>

Functor<Promise, Integer, Promise<Integer>> p1 = functor(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2 = p1.map(i -> i + 1);

Applicative

In PromiseHelper applicative<T> :: Promise<T> → Applicative<T>

Applicative<Promise, Integer, Promise<Integer>> p1 = applicative(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2  = p1.apply(functor(executor.async(() -> i -> i + 1)));

Monad

In PromiseHelper monad<T> :: Promise<T> → Monad<T>

Monad<Promise, Integer, Promise<Integer>> p1 = monad(executor.async(() -> 1));
HK<Promise, Integer, Promise<Integer>> p2 = p1.flatmap(i -> executor.async(() -> i + 1));

CompletableFuture and Promise

In CompletableFutureHelper completableFuture<T> :: Promise<T> → CompletableFuture<T>

Executor executor = ExecutorHelper.create(Executors.newSingleThreadExecutor());
Promise<String> helloWorldPromise = executor.async(() -> "Hello").and(s -> s + " world!");
CompletableFuture<String> completable = CompletableFutureHelper.completableFuture(helloWorldPromise);

In CompletableFutureHelper promise<T> :: CompletableFuture<T> → Promise<T>

CompletableFuture<String> completable = CompletableFutureHelper.supplyAsync(() -> "Hello World");
Promise<String> helloWorldPromise = CompletableFutureHelper.promise(completable);

Releases

This library is available at Sonatype OSS Repository Hosting service and can be simply used adding the following dependency - for instance - to your pom project.

<dependency>
  <groupId>org.smallibs</groupId>
  <artifactId>hpas</artifactId>
  <version>0.12.6</version>
</dependency>

About the library design

The library has been designed simulating High Order Type in Java and self type thanks to F-Bounded quantification polymorphism.

For more information follow this link.

License

Copyright (C)2016-2025 D. Plaindoux.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

About

Functional ADT And Asynchronous stuff in Java

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages