Lisp unroll / partial eval function

Is there a way to show the steps of evaluation in Common Lisp like this:

> (defun fac (n) (if (= n 0) 0 (if (= n 1) 1 (* n (fac (- n 1))))))
FAC
> (step-by-step (fac 3))
0: (FAC 3)
1: (* 3 (FAC 2))
3: (* 3 (* 2 (FAC 1)))
4: (* 3 (* 2 (1)))
5: (* 3 2)
6: 6
Result: 6

      

Looking for a way to visualize recursion and return values ​​in general for a small course. I know (step fn)

and (optimize (debug 3)))

unfortunately it doesn’t give the desired result, or I don’t know how to say it.

NOTE: preferred solution other than emacs / slime

+3


source to share


1 answer


This is not all you asked and the exact result is implementation dependent, but you can get a good idea from the standard trace . It won't show the extension as you showed, but it is definitely a way to satisfy some of your requirements.

[to] render recursion and return values ​​in general & hellip; to see the whole expression at every step. As well as debugging printing every function call.

Many implementations include additional arguments that can customize how things are tracked, what is printed, etc. Here's an example of the default behavior with SBCL:



CL-USER> (defun fac (n) (if (= n 0) 0 (if (= n 1) 1 (* n (fac (- n 1))))))
FAC
CL-USER> (trace fac)
(FAC)
CL-USER> (fac 3)
  0: (FAC 3)
    1: (FAC 2)
      2: (FAC 1)
      2: FAC returned 1
    1: FAC returned 2
  0: FAC returned 6
;=> 6

      

In CLISP:

CL-USER> (fac 3)
1. Trace: (FAC '3)
2. Trace: (FAC '2)
3. Trace: (FAC '1)
3. Trace: FAC ==> 1
2. Trace: FAC ==> 2
1. Trace: FAC ==> 6
;=> 6

      

+6


source







All Articles