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))))