Should I avoid tail recursion in Prolog and in general?

前端 未结 5 1745
后悔当初
后悔当初 2020-12-02 01:49

I\'m working through \"Learn Prolog now\" online book for fun.

I\'m trying to write a predicate that goes through each member of a list and adds one to it, using acc

5条回答
  •  隐瞒了意图╮
    2020-12-02 02:08

    In contrast to so some other programming languages, certain Prolog implementations are well suited for tail recursive programs. Tail recursion can be handled as a special case of last call optimization (LCO). For example this here in Java doesn't work:

    public static boolean count(int n) {
        if (n == 0) {
            return true;
        } else {
            return count(n-1);
        }
    }
    
    public static void main(String[] args) {
        System.out.println("count(1000)="+count(1000));
        System.out.println("count(1000000)="+count(1000000));
    }
    

    The result will be:

    count(1000)=true
    Exception in thread "main" java.lang.StackOverflowError
        at protect.Count.count(Count.java:9)
        at protect.Count.count(Count.java:9)
    

    On the other hand major Prolog implementations don't have any problem with it:

     ?- [user].
     count(0) :- !.
     count(N) :- M is N-1, count(M).
     ^D
    

    The result will be:

    ?- count(1000).
    true.
    ?- count(1000000).
    true.
    

    The reason Prolog systems can do that, is that their execution is most often anyway trampolin style, and last call optimization is then a matter of choice point elimination and environment trimming. Environment trimming was already documented in early WAM.

    But yes, debugging might be a problem.

提交回复
热议问题