Stack overflow from recursive function call in Lisp

后端 未结 4 468
再見小時候
再見小時候 2020-12-31 16:38

I am learning Lisp from the book \"The Land of Lisp\" by Conrad Barski. Now I have hit my first stumbling block, where the author says:

Calling yourse

4条回答
  •  说谎
    说谎 (楼主)
    2020-12-31 17:00

    TCO (tail call optimization) in CLISP using the example from Chris Taylor:

    [1]> (defun helper (acc list)
           (if list
               (helper (1+ acc) (cdr list))
               acc))
    
    (defun my-length (list)
      (helper 0 list))
    
    HELPER
    

    Now compile it:

    [2]> (compile 'helper)
    MY-LENGTH
    [3]> (my-length (loop repeat 100000 collect t))
    
    *** - Program stack overflow. RESET
    

    Now, above does not work. Let's set the debug level low. This allows the compiler to do TCO.

    [4]> (proclaim '(optimize (debug 1)))
    NIL
    

    Compile again.

    [5]> (compile 'helper)
    HELPER ;
    NIL ;
    NIL
    [6]> (my-length (loop repeat 100000 collect t))
    100000
    [7]> 
    

    Works.

    Allowing the Common Lisp compiler to do TCO is most often controlled by the debug level. With a high debug level, the compiler generates code which uses a stack frame for each function call. This way each call can be traced and will be seen in a backtrace. With a lower debug level the compiler may replace tail calls with jumps in the compiled code. These calls then will not be seen in a backtrace - which usually makes debugging harder.

提交回复
热议问题