3.3 Using Debugger commands

3.3.6 Returning values from the current frame

The:r command allows you to continue an evaluation by returning a value or values to the caller of the current frame. The following example defines a recursive function that takes a list of numbers and returns a list of the square roots of the elements in the argument list:

> (defun square-root-list (integer-list)
    (check-type integer-list list)
    (let ((entry (first integer-list)))
      (if (minusp entry)
          '()
          (cons (isqrt entry) 
                (square-root-list (rest integer-list))))))
SQUARE-ROOT-LIST
The argument to the functionsquare-root-list must be a list of numbers; otherwise, an error is signaled. The function stops when it encounters the first negative entry in the argument list. In the following example, the functionsquare-root-list is passed an argument that is a list of numbers:

> (square-root-list '(10 3 7))
>>Error: The value of X, NIL, should be a NUMBER
MINUSP:
   Required arg 0 (X): NIL
:C  0: Use a new value
:A  1: Abort to Lisp Top Level
-> 

An error is signaled even though the argument passed to the function was a list of numbers; thus, an error exists in the function. Examining the value of the argumentx that is passed to each recursive call to the functionsquare-root-list might reveal something about the error.

Moving to the most recent call tosquare-root-list with the:n command shows that the function was passed a value ofnil:

-> :n
SQUARE-ROOT-LIST:
Original code: (NAMED-LAMBDA SQUARE-ROOT-LIST (INTEGER-LIST) 
(BLOCK SQUARE-ROOT-LIST (CHECK-TYPE INTEGER-LIST LIST) 
(LET # #)))
   Required arg 0 (INTEGER-LIST): NIL
-> 

You can move to the previous stack frame and examine the values of the local variables for that frame by using the:n command:

-> :n
SQUARE-ROOT-LIST:
Original code: (NAMED-LAMBDA SQUARE-ROOT-LIST (INTEGER-LIST) 
(BLOCK SQUARE-ROOT-LIST (CHECK-TYPE INTEGER-LIST LIST) 
(LET # #)))
   Required arg 0 (INTEGER-LIST): (7)
-> 

In this call tosquare-root-list, the value ofx is(7), which indicates that the current frame received a valid argument. That is, the argument is a list containing one number.

Move to the previous frame and examine the value ofx:

-> :n
SQUARE-ROOT-LIST:
Original code: (NAMED-LAMBDA SQUARE-ROOT-LIST (INTEGER-LIST) 
(BLOCK SQUARE-ROOT-LIST (CHECK-TYPE INTEGER-LIST LIST) 
(LET # #)))
   Required arg 0 (INTEGER-LIST): (3 7)
-> 

In this stack frame, the value of the variable is(3 7); thus, a pattern has emerged. The functionsquare-root-list is called recursively with a different value passed to each recursion. As you move back through the stack, you can see that previous calls to the function were passed a list of positive integers. The most recent recursion, however, was passed a value ofnil; becausenil fails the check byminusp, the Debugger is entered.

You can complete the evaluation by returning a list as the value of the current recursive call tosquare-root-list. A correct value is then passed to each of the previous calls tosquare-root-list and the evaluation is completed.

First, return to the frame that contains the most recent call tosquare-root-list by entering the:< command withsquare-root-list as the command argument:

-> :< square-root-list
SQUARE-ROOT-LIST:
Original code: (NAMED-LAMBDA SQUARE-ROOT-LIST (INTEGER-LIST) 
(BLOCK SQUARE-ROOT-LIST (CHECK-TYPE INTEGER-LIST LIST) 
(LET # #)))
   Required arg 0 (INTEGER-LIST): NIL
-> 

Specify a value or values to return to the previous frame by using the:r command. This command returns one or more specified values from the current frame; these values are then used in the remainder of the interrupted evaluation.

The following example specifies an empty list to be returned by the current frame instead ofnil, thus completing the evaluation:

-> :r '()
(3 1 2)
> 

Note: After you have debuggedsquare-root-list, you should redefine it in the source code so that it contains a conditional expression that checks whether the current argument is null before the function checks for a negative number:

(defun square-root-list (integer-list)
  (check-type integer-list list)
  (let ((entry (first integer-list)))
    (if (or (not (integerp entry))
            (minusp entry))
        '()
        (cons (isqrt entry) 
              (square-root-list (rest integer-list))))))


The User's Guide - 9 SEP 1996

Generated with Harlequin WebMaker