Ken
Ken

Reputation: 5224

Does any Common Lisp function return 3 values?

Does any Common Lisp (builtin) function return more than 2 values? I know many that return 2, but I can't think of one that returns 3.

(I saw a comment here about returning more than 2 values, and tried to think of a case where CL did this, but can't.)

Upvotes: 3

Views: 2058

Answers (4)

David Lichteblau
David Lichteblau

Reputation: 3561

Yes, such functions exist. Here is the complete list of functions in the COMMON-LISP package that return exactly three values, as declared in SBCL source code:

COMPILE                                 required: 3, optional: 0, rest?: NIL
INTEGER-DECODE-FLOAT                    required: 3, optional: 0, rest?: NIL
COMPILE-FILE                            required: 3, optional: 0, rest?: NIL
GET-PROPERTIES                          required: 3, optional: 0, rest?: NIL
FUNCTION-LAMBDA-EXPRESSION              required: 3, optional: 0, rest?: NIL
DECODE-FLOAT                            required: 3, optional: 0, rest?: NIL
RENAME-FILE                             required: 3, optional: 0, rest?: NIL

In addition, the following functions return a constant number of values greater than three:

DECODE-UNIVERSAL-TIME                   required: 9, optional: 0, rest?: NIL
GET-DECODED-TIME                        required: 9, optional: 0, rest?: NIL

These functions return a variable number of values, hence possibly more than three:

NO-APPLICABLE-METHOD                    required: 0, optional: 0, rest?: T
NO-NEXT-METHOD                          required: 0, optional: 0, rest?: T
VALUES                                  required: 0, optional: 0, rest?: T

(I've omitted some functions from this list where SBCL does not declare
a values type explicitly.  get-setf-expansion is one of them.)

Explanations of the columns: required is minimum number of return values for these functions, optional a fixed number of return values which SBCL thinks might or might not be returned, rest? indicates that a variable number of values is expected. (Only macroexpand and macroexpand-1 actually use &optional, don't ask me why.)

And just for fun, here is the source code I used to come up with these tables:

(do-external-symbols (sym :common-lisp)                                         
  (when (fboundp sym)                                                           
    (multiple-value-bind (required optional rest)                               
        (let ((fun-type (sb-int:info :function :type sym)))                     
          (etypecase fun-type                                                   
            (sb-kernel:fun-type                                                 
             (let ((returns                                                     
                    (sb-kernel:fun-type-returns fun-type)))                     
               (etypecase returns                                               
                 (sb-kernel:values-type                                         
                  (values (length (sb-kernel:values-type-required returns))     
                          (length (sb-kernel:values-type-optional returns))     
                          (sb-kernel:values-type-rest returns)))                
                 (sb-kernel:named-type                                          
                  (if (sb-kernel:named-type-name returns)                       
                      (values 1 0 t)                                          
                      (values 0 0 nil))))))                                     
            (t                                                                  
             (values 0 0 t))))                                                  
      (format t                                                                 
              "~A~40Trequired: ~D, optional: ~D, rest?: ~A~%"                   
              sym                                                               
              required optional rest))))

Upvotes: 27

kmkaplan
kmkaplan

Reputation: 18960

decode-universal-time returns nine values.

Upvotes: 7

user4010
user4010

Reputation: 189

VALUES and VALUES-LIST, among others.

Upvotes: 2

dmitry_vk
dmitry_vk

Reputation: 4469

There is a get-setf-expansion function. It returns 5 values.

Upvotes: 4

Related Questions