Search code examples
javastackstack-overflowchicken-scheme

How can I check the stack limits, and accomplish Chicken Scheme style recursion in Java?


Consider the following code. This code almost implements Chicken Scheme style recursion where most of the time functions are directly called but occasionally there is a more complicated trampolining procedure. However, the code doesn't quite work correctly. What I really want is a method stackLimitsAlmostReached that returns a boolean value that indicates if there is a danger of a stack overflow. How can I check stack limits, and accomplish Chicken Scheme style recursion in Java?

import java.util.Scanner;

public class Main {

public static abstract class Thunk {
    public abstract Thunk x();

    public final void run() {
        Thunk ip = this;

        while (ip != null)
            ip = ip.x();
    }
}

public static void main(String[] unused) {
    final Scanner scanner = new Scanner(System.in);

    new Thunk() {
        public Thunk x() {
            System.out.println("Hello World!");

            try {
                return this.x();
            } catch (StackOverflowError t) {
                System.out.println("GC!");
                scanner.nextLine();
                return this;
            }
        }
    }.run();
}
}

Solution

  • Hey i may have misunderstood your question , but i think that you must look first for these options (Java wise , but this is isn't the problem IMO)

    -ss Stacksize to increase the native stack size or
    
    -oss Stacksize to increase the Java stack size,
    

    The default native stack size is 128k, with a minimum value of 1000 bytes. The default java stack size is 400k, with a minimum value of 1000 bytes.

    But what i really feel i should warn you about is that the JVM can't support tail call optimisation because of it's security model. Wikipedia . Each time you call the same function , you introduce a new stack frame and that's why you run on limits fast. A proper scheme that supports TCO doesn't actually create a new stack frame , it just updates the values and returns to a continuation at the start of the current frame. this makes recursion very efficient.

    Even clojure that runs on the JVM suffers from this problem , that's why it has a lambda called recur to handle that limitation. check also : TCO paper