Search code examples
lispcommon-lispclisp

Lisp: How to obtain the final loop value?


(defun index-iteration (n) 
  (let ((x 0))
    (loop for j from 0 to n while (< x n) do
      (setf x (max-index-for-iteration j)))))

I have the following lisp code, at the end of the loop I want to return the value j. I have investigated:

  • collect but that returns a list of values with the value I want (the last j at the end)
  • finally but it didn't work.
  • return but it ends the loop early

Solution

  • You need to combine finally and return like this:

    (loop ...
      finally (return (1- j)))
    

    Please note the unfortunate use of 1- which is due to the fact that the finally clause is executed after the termination clause (while in your case) transfers control there. IOW, it requires the knowledge about how the termination clause is handled.

    You can stay within the loop domain (without the extra let) like this:

    (loop for j from 0 to n
      for ret = j
      do ...
      finally (return ret))
    

    You could also use the maximize clause:

    (loop for j from 0 to n ...
      maximize j)
    

    but this relies on the knowledge that the final value of j was the maximum one.

    PS. Note also that you do not need the while clause in your loop.