All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thejohnfreeman.lazy.Lazy Maven / Gradle / Ivy

Go to download

A library for type-safe, tractable lazy evaluation and late binding in Java.

The newest version!
package com.thejohnfreeman.lazy;

import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

import com.thejohnfreeman.function.Function3;
import com.thejohnfreeman.function.Function4;
import com.thejohnfreeman.function.Function5;
import com.thejohnfreeman.function.Function6;

/**
 * A lazy value with dependencies.
 *
 * 

* A lazy value is stateful. Before it is forced, it can return its * dependencies, but not its value. After it is forced, it can return its value, * but might not be able to return its (former) dependencies. * *

* A lazy value cannot be forced until all of its dependencies are forced. * An iterative algorithm for forcing a directed acyclic graph of lazy values * is provided as the default implementation of {@link #force()}. It is the * recommended interface for forcing evaluation. * *

* Note: In generic implementing types from this package, the value type is * always the first type parameter, unlike functional interfaces, where the * result type is always the last type parameter. */ @SuppressWarnings("PMD.TooManyMethods") public interface Lazy { /** * Returns whether this value has been forced yet. * * @return {@code true} iff this value has been successfully forced */ boolean isForced(); /** * Returns an immutable list of this value's dependencies. * * @return an immutable list of this value's dependencies * @throws IllegalStateException if {@code isForced()} */ Iterable> getDependencies() throws IllegalStateException; /** * Evaluates and returns this value. May only be called once. Assumes all * of its dependencies are forced. Generally, you should call * {@link #force()} instead. * * @return the value * @throws IllegalStateException * if any dependencies are unforced, or if {@code isForced()} * @see #force() */ T forceThis() throws IllegalStateException; /** * Evaluates and returns this value. * * @return the value * @throws IllegalStateException * if any transitive dependencies cannot be evaluated */ default T force() throws IllegalStateException { return Force.force(this); } /** * Returns this value. May not be called unless {@code isForced()}. * * @return the value * @throws IllegalStateException if {@code !isForced()} * @see #force() */ T getValue() throws IllegalStateException; default String toStringUnforced(final String name) { return "() -> " + name; } static LateBound delay() { return LateBound.of(); } static TaggableLazy delay(final T value) { return Constant.of(value); } static TaggableLazy delay( final Lazy a, final Function func) { return Thunk1.of(a, func); } static TaggableLazy delay( final Lazy a, final Lazy b, final BiFunction func) { return Thunk2.of(a, b, func); } static TaggableLazy delay( final Lazy a, final Lazy b, final Lazy c, final Function3 func) { return Thunk3.of(a, b, c, func); } static TaggableLazy delay( final Lazy a, final Lazy b, final Lazy c, final Lazy d, final Function4 func) { return Thunk4.of(a, b, c, d, func); } static TaggableLazy delay( final Lazy a, final Lazy b, final Lazy c, final Lazy d, final Lazy e, final Function5 func) { return Thunk5.of(a, b, c, d, e, func); } static TaggableLazy delay( final Lazy a, final Lazy b, final Lazy c, final Lazy d, final Lazy e, final Lazy f, final Function6 func) { return Thunk6.of(a, b, c, d, e, f, func); } static TaggableLazy delay( final Collection> lazies, final Function, T> func) { return CollectionThunk.of(lazies, func); } static TaggableLazy> sequence( final Collection> lazies) { return CollectionThunk.sequence(lazies); } }