Closures in Karel

Java supports anonymous functions through lambda expressions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

import java.util.function.Supplier;

public class Closures {
    // This method returns a Supplier<Integer>, which is a functional interface
    // representing a supplier of results. The returned lambda expression
    // closes over the variable i to form a closure.
    public static Supplier<Integer> intSeq() {
        final int[] i = {0};  // We use an array to hold a mutable int
        return () -> ++i[0];
    }

    public static void main(String[] args) {
        // We call intSeq, assigning the result (a Supplier<Integer>)
        // to nextInt. This lambda 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 function, create and test a new one.
        Supplier<Integer> newInts = intSeq();
        System.out.println(newInts.get());
    }
}

To run this program:

$ javac Closures.java
$ java Closures
1
2
3
1

In this Java version, we use a Supplier<Integer> functional interface to represent a function that takes no arguments and returns an integer. The intSeq() method returns a lambda expression that increments and returns a captured integer.

Java doesn’t allow modifying local variables from within lambda expressions, so we use an array with a single element to hold our mutable integer. This is a common workaround in Java to simulate mutable closure variables.

The main method demonstrates how the closure works, showing that each Supplier<Integer> maintains its own state.

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