Code: Select all
* (step (fibo 5))
; Evaluating call:
; (FIBO 5)
; With arguments:
; 5
1]
Code: Select all
* (step (fibo 5))
; Evaluating call:
; (FIBO 5)
; With arguments:
; 5
1]
Code: Select all
* (defun test-step () (declare (optimize (debug 3)))(print 'a)(print 'b)(print 'c))
TEST-STEP
* (step (test-step))
; Evaluating call:
; (TEST-STEP)
; With arguments:
;
1] :step
; Evaluating call:
; (PRINT 'A)
; With arguments:
; A
1] :next
; Evaluating call:
; (PRINT 'B)
; With arguments:
; B
A
1] :next
; Evaluating call:
; (PRINT 'C)
; With arguments:
; C
B
1] :next
; (TEST-STEP) => C
C
C
SBCL manual wrote:> (max speed space compilation-speed)
If debug is greater than all of speed, space and compilation-speed the code will be steppable (see Single Stepping).
Code: Select all
(declare (optimize (debug 3)))
It is mentioned in the first paragraph of the manual. Reading documentation is usually more productive than guessing. You can set compiler policy using top level declaim. Note that as the Hyperspec says, it is unspecified if delaimations are file-specific or global, but for debugging you can just do a DECLAIM from the REPL before compilation.speech impediment wrote:Aha. I missed this bit:
In tail recursion there is not top to cycle back to by definition.speech impediment wrote:I think when it evaluates a tail recursive call, it seems to just compress the recursion and it doesn't cycle back to the top
You can declaim it before any functions you want to step through.speech impediment wrote:I don't suppose there is a way to avoid putting this in each and every function is there?
Code: Select all
(declaim (optimize (debug 3)))
Not sure what you mean so I will cast a few lines: setting debug setting high often times disables tail call optimization, and at least naive a implementation of Fibonacci doesn't have tail calls anyway, but maybe you are using something more sophisticated? Be that as it may, when I tried this, stepping into the lower fibo calls acted as I expected, cycling back to the top, at least in SBCL. So that it weird... Why don't you post a repl transcript from a fresh image to demonstrate.speech impediment wrote:I think when it evaluates a tail recursive call, it seems to just compress the recursion and it doesn't cycle back to the top
Really? It is still calling the function recursively, it just isn't returning to that frame. Am I wrong?Ramarren wrote:In tail recursion there is not top to cycle back to by definition.
The manual does allude to different levels of stepability, but the debug policy page seems to suggest that (> debug (max speed space compilation-speed)) is the only factor. So unless there are some SBCL internals people here, you could drop by #lisp on irc.freenode.net and ask them there.speech impediment wrote:So is this setting the most detailed stepping?
I might not get what is the 'top' here. I interpreted is a something to do with a higher stack frame, which contains nothing. Obviously execution jumps to the top of the function with new arguments, but that does happen with SBCL stepper.smithzv wrote:Really? It is still calling the function recursively, it just isn't returning to that frame. Am I wrong?
Code: Select all
* (defun recur (list) (declare (optimize (debug 3))) (print (car list))(if list (recur (cdr list))))
STYLE-WARNING: redefining RECUR in DEFUN
RECUR
* (step (recur '(1 2 3)))
; Evaluating call:
; (RECUR '(1 2 3))
; With arguments:
; (1 2 3)
1] step
; Evaluating call:
; (PRINT (CAR LIST))
; With arguments:
; 1
1] next
; Evaluating call:
; (RECUR (CDR LIST))
; With arguments:
; (2 3)
1
1] step
; Evaluating call:
; (PRINT (CAR LIST))
; With arguments:
; 2
1] next
; Evaluating call:
; (RECUR (CDR LIST))
; With arguments:
; (3)
2
1] step
; Evaluating call:
; (PRINT (CAR LIST))
; With arguments:
; 3
1] next
; Evaluating call:
; (RECUR (CDR LIST))
; With arguments:
; NIL
3
1] step
; Evaluating call:
; (PRINT (CAR LIST))
; With arguments:
; NIL
1] next
; (RECUR (CDR LIST)) => NIL
; (RECUR (CDR LIST)) => NIL
; (RECUR (CDR LIST)) => NIL
; (RECUR '(1 2 3)) => NIL
NIL
NIL
I am not sure what you mean, but after perusing the hyperspec, I presume you are talking about having (declare (optimize (debug 3))) outside of the function and replace declare with declaim. Like this:You can declaim it before any functions you want to step through.
Code: Select all
(declaim (optimize (debug 3)))
(defun test-step () (print 'a)(print 'b)(print 'c))
Code: Select all
(defun fibo (n) (declare (optimize (debug 3)))
(cond ((equal n 0) 1)
((equal n 1) 1)
(t (+ (fibo (- n 1)) (fibo (- n 2))))))
* (step (fibo 5))
; Evaluating call:
; (FIBO 5)
; With arguments:
; 5
1] :step
; Evaluating call:
; (EQUAL N 0)
; With arguments:
; 5
; 0
1] :next
; Evaluating call:
; (EQUAL N 1)
; With arguments:
; 5
; 1
1] :next
; Evaluating call:
; (- N 1)
; With unknown arguments
0] :next
; Evaluating call:
; (FIBO (- N 1))
; With arguments:
; 4
1] :next
; Evaluating call:
; (- N 2)
; With unknown arguments
0] :next
; Evaluating call:
; (FIBO (- N 2))
; With arguments:
; 3
1] :next
; Evaluating call:
; (+ (FIBO (- N 1)) (FIBO (- N 2)))
; With unknown arguments
0] :next
; (FIBO 5) => 8
8
*
I explained it in very first reply: :next evaluates the expression as the whole and goes to the next one, :step steps into it. You have to use :step to step into recursive calls. Or any calls.speech impediment wrote:So if you scroll all the way down, once it creates the two branches, the result is given and there are no more branches to step through.
Addition is a primitive operation and doesn't have anything to step through. Well, I suppose there is type dispatch and so, but why would you want to step SBCL internals?speech impediment wrote:It doesn't even step through the process of addition.
This is clear now.I explained it in very first reply: :next evaluates the expression as the whole and goes to the next one, :step steps into it. You have to use :step to step into recursive calls. Or any calls.
Well, I was learning about order of evaluation; Normal order vs. Applicative order. How side effects effects does matter in order of evaluation, etc. So I was thinking if I miscalculate order of evaluation and get an outcome I did not understand, it would be helpful. Also, there might be situations where I was dumb enough to mix up something like this: (/ (+ 1 1)(/ 3 3)) and expect that I was doing this: 1/2. However, I do see you point now that I was able to step through my code. Forgive my ignorance again, but I can't seem to find type dispatch in the hyperspec. What is that?Addition is a primitive operation and doesn't have anything to step through. Well, I suppose there is type dispatch and so, but why would you want to step SBCL internals?