Question

I have this list code block.

(defun test (y)
    (do 
        ((l NIL (setq y (rest y))))
        ((null y) 1)
        (setq l (append l '(1 1)))
        (print l)
    )
)

And the output is pictured below. For some reason it's setting l to y and then appending '(1 1). Can anyone explain this behavior?

enter image description here

Was it helpful?

Solution

The structure of a do loop is:

(do ((var init-form step-form))
    (termination-form result-form)
  (body))

I think what you're missing is that step-form is executed at every iteration and the result of this form is set to the variable. So using setq in the step-form is a flag that you're probably not doing what you intend.

So the sequence of the loop from (test '(2 3 4)) is (eliding the print)

 - Initialize l to nil
 - Check (null y) which is false since y = '(2 3 4).
 - (setq l (append l '(1 1))) l now has the value '(1 1)
 - Execute the step form, this sets y = '(3 4) _and_ l = '(3 4)
 - (null y) still false.
 -  (setq l (append l '(1 1))) sets l = '(3 4 1 1)
 - Execute step form, sets y = '(4) _and_ l = '(4)
 - (setq l (append l '(1 1))) sets l = '(4 1 1)
 - Execute step form, y = () so loop terminates.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top