Closures in CLIPS

Java supports anonymous classes and methods, which can form closures. Anonymous classes and methods are useful when you want to define a class or method inline without having to name it.

import java.util.function.Supplier;

public class Closures {

    // This method intSeq returns a Supplier<Integer>, which we define
    // anonymously in the body of intSeq. The returned Supplier
    // closes over the variable i to form a closure.
    public static Supplier<Integer> intSeq() {
        final int[] i = {0};
        return () -> {
            i[0]++;
            return i[0];
        };
    }

    public static void main(String[] args) {
        // We call intSeq, assigning the result (a Supplier<Integer>)
        // to nextInt. This Supplier captures its own i value,
        // which will be updated each time we call nextInt.get().
        Supplier<Integer> nextInt = intSeq();

        // See the effect of the closure by calling nextInt.get()
        // a few times.
        System.out.println(nextInt.get());
        System.out.println(nextInt.get());
        System.out.println(nextInt.get());

        // To confirm that the state is unique to that
        // particular Supplier, create and test a new one.
        Supplier<Integer> newInts = intSeq();
        System.out.println(newInts.get());
    }
}

When you run this program, you’ll see the following output:

1
2
3
1

In this Java example, we use the Supplier<Integer> functional interface to create a closure. The intSeq method returns a Supplier<Integer> that increments and returns a counter each time it’s called.

The closure is created by the anonymous lambda expression that captures the i array. We use an array of size 1 instead of a simple int because Java requires variables used in lambda expressions to be effectively final.

In the main method, we demonstrate how the closure maintains its own state across multiple invocations, and how creating a new closure starts with a fresh state.

The last feature of methods we’ll look at for now is recursion.