Ленивый пример

Код на потестить, с лекции, с ленивыми функциями

public class Main {
    // основной интерфейс для объявления функции
    interface Fn {
        int get();
    }

    // функциональная переменная
    static class Var implements Fn {
        int value;

        public Var(int value) {
            this.value = value;
        }

        public int get() {
            return value;
        }

        // для изменения значения переменной
        public void set(int value) {
            this.value = value;
        }
    }


    public static Fn add(Fn x1, Fn x2) {
        return () ->{
            // я добавил sout сюда, чтобы можно было проверить,
            // что код действительно считается лениво
            // пока get не будет вызыван ни один System.out не сработает
            System.out.println("считаю add");
            return x1.get() + x2.get();
        };
    }

    public static Fn sub(Fn x1, Fn x2) {
        return () ->{
            System.out.println("считаю sub");
            return x1.get() - x2.get();
        };
    }

    public static Fn div(Fn x1, Fn x2) {
        return () ->{
            System.out.println("считаю div");
            return x1.get() / x2.get();
        };
    }

    public static Fn mult(Fn x1, Fn x2) {
        return () ->{
            System.out.println("считаю mult");
            return x1.get() * x2.get();
        };
    }

    public static Fn power2(Fn x) {
        return () ->{
            System.out.println("считаю power2");
            return x.get() * x.get();
        };
    }

    public static Fn value(int value) {
        return () ->{
            System.out.println("считаю value");
            return value;
        };
    }

    public static void main(String[] args) {
        // объявил три переменных
        Var a = new Var(1);
        Var b = new Var(2);
        Var c = new Var(3);

        // описал формулу: b^2 - 4ac
        Fn D1 = sub(power2(b), mult(value(4), mult(a, c)));
        System.out.println(D1.get()); // выдаст -8

        // а можно так объявить чтобы value не использовать
        Fn D2 = sub(power2(b), mult(() -> 4, mult(a, c)));
        System.out.println(D2.get()); // выдаст -8

        // изменил значение переменной
        b.set(10);
        System.out.println(D2.get()); // выдаст 88
    }
}