Search code examples
functionreturnlispcommon-lisp

Why does my function return multiple values without values keyword in lisp


I would like to ask why does my function not require to use the values function in order to output a nested list?

(defun p2 (l)
(cond
 ((null l) nil)
 ((listp (car l)) ( values (p2 (car l)) (p2 (cdr l))) )
 (t (princ (car l)) (princ " ") (p2 (cdr l)))
 ))

I mean doesn't the cond construct return 1 value or take 1 action if the condition is true?
And why does this work?


Solution

  • (defun p2 (l)
      (cond
        ((null l) ; condition
         nil)     ; body
        ((listp (car l))         ; condition
         (values (p2 (car l))    ; \
                 (p2 (cdr l))))  ; /` body
        (t                ; condition
         (princ (car l))  ; \
         (princ " ")      ;  > body
         (p2 (cdr l)))))  ; /
    

    This cond form has three clauses. Each clause is a list where the first element is a condition and the rest is a body. Cond looks at each clause in turn until it finds one where the condition is true. It then executes the body of that clause in an implicit progn. Progn returns all the values returned by the last form of its body. Cond returns all the values returned by the matching clause. A function returns all the values returned by its body (which is another implicit progn).

    As to the “why”: it is defined in this (quite sensible) manner in the standard, and the implementations implement it this way.