package org.xander.behavioral.lazyevaluation;

@FunctionalInterface
public interface TailCall<T> {
    TailCall<T> apply();
    default boolean isComplete() { return false; }
    default T result() { throw new Error("not implemented"); }
    default T invoke() {
        return Stream.iterate(this, TailCall::apply)
                     .filter(TailCall::isComplete)
                     .findFirst()
                     .get()
                     .result();
    } 
}

package org.xander.behavioral.lazyevaluation;

import java.util.stream.Stream;

@FunctionalInterface
public interface TailCall<T> {
    TailCall<T> apply();
    default boolean isComplete() { return false; }
    default T result() { throw new Error("not implemented"); }
    default T invoke() {
        return Stream.iterate(this, TailCall::apply)
                     .filter(TailCall::isComplete)
                     .findFirst()
                     .get()
                     .result();
    } 
}

Update TailCall.java