0.0.1

for-comprehension
4j

Bring Scala's for-expression syntax to Java. Compose Optional, Stream, and Iterable without deep nesting. Eager and lazy evaluation with optional filter/guard clauses.

com.pivovarit:for-comprehension4j:0.0.1 click to copy

No more flatMap
spaghetti

Flatten nested monadic chains into clean, readable comprehensions — the way Scala does it.

Scala-inspired

Brings Scala's for-expression syntax to Java, eliminating deeply nested flatMap and map chains.

Multiple types

Supports Optional, Stream, and Iterable out of the box, with consistent semantics across all container types.

Eager & Lazy

Eager mode for independent values provided upfront; lazy mode when later bindings depend on earlier ones.

Filter / Guards

Optional .filter() step that acts as a guard clause. Multiple calls are AND-composed automatically.

Fluent API

Chain bindings naturally and terminate with .yield() to produce the result. Clean and readable at any arity.

JDK 8+

Compatible with Java 8 and above. No exotic runtime requirements, no virtual threads, no module system.

Comprehensions
in practice

All examples use import static com.pivovarit.forc.ForComprehension.forc;

// Eager: all values known upfront
Optional<Integer> width  = Optional.of(3);
Optional<Integer> height = Optional.of(4);

Optional<Integer> area = forc(width, height)
  .yield((w, h) -> w * h);

// area -> Optional[12]

// Lazy: second value depends on first
Optional<Integer> area2 = forc(
    Optional.of(3),
    w -> Optional.of(w + 1)
  ).yield((w, h) -> w * h);

// area2 -> Optional[12]
// Eager: cartesian product
Stream<Integer> result = forc(
    Stream.of(1, 2),
    Stream.of(10, 20)
  ).yield(Integer::sum);

// result -> [11, 21, 12, 22]

// Lazy: second stream depends on first
Stream<Integer> result2 = forc(
    Stream.of(1, 2),
    v1 -> Stream.of(v1 * 10, v1 * 20)
  ).yield(Integer::sum);

// result2 -> [11, 21, 22, 42]
// Eager
List<Integer> result = forc(
    List.of(1, 2),
    List.of(10, 20)
  ).yield(Integer::sum);

// result -> [11, 21, 12, 22]

// Lazy
List<Integer> result2 = forc(
    List.of(1, 2),
    v1 -> List.of(v1 * 10, v1 * 20)
  ).yield(Integer::sum);

// result2 -> [11, 21, 22, 42]
// Optional — guard failure produces empty()
Optional<Integer> area = forc(
    Optional.of(4), Optional.of(3)
  ).filter((w, h) -> w > h)
   .yield((w, h) -> w * h);
// area -> Optional[12]  (4 > 3, guard passes)

// Stream — guard filters the cartesian product
Stream<String> allowed = forc(
    Stream.of("admin", "user"),
    Stream.of("read", "write")
  ).filter((role, scope) -> !(role.equals("user") && scope.equals("write")))
   .yield((role, scope) -> role + ":" + scope);
// allowed -> ["admin:read", "admin:write", "user:read"]

Core operations

Static factory method forc() on ForComprehension — inspired by Scala's for/yield expressions.

forc(v1, v2, ...) Comprehension

Eager overload. All values are provided upfront. The result type mirrors the container (Optional → Optional, Stream → Stream, Iterable → List).

forc(v1, fn2, ...) Comprehension

Lazy overload. Later values are functions of the preceding ones, enabling dependent bindings where each step can reference earlier results.

.filter(predicate) Comprehension

Guard clause. Keeps only combinations where the predicate holds. Multiple .filter() calls are AND-composed automatically.

.yield(fn) R

Terminal operation. Applies the mapping function to all bound values and produces the final result: Optional<R>, Stream<R>, or List<R>.

// All types use the same forc() + .yield() pattern

// Optional → Optional<R>
Optional<String> r1 = forc(Optional.of("a"), Optional.of("b"))
  .yield((a, b) -> a + b);

// Stream → Stream<R>  (cartesian product)
Stream<String> r2 = forc(Stream.of("x", "y"), Stream.of("1", "2"))
  .yield((a, b) -> a + b);

// Iterable → List<R>
List<String> r3 = forc(List.of("x", "y"), List.of("1", "2"))
  .yield((a, b) -> a + b);

Add to your project

Maven

JDK 8+
<dependency>
  <groupId>com.pivovarit</groupId>
  <artifactId>for-comprehension4j</artifactId>
  <version>0.0.1</version>
</dependency>

Gradle

JDK 8+
implementation 'com.pivovarit:for-comprehension4j:0.0.1'
Available on Maven Central. Requires Java 8 or above.