Une fonction Common Lisp renvoie-t-elle 3 valeurs?
-
20-08-2019 - |
Question
Est-ce qu'une fonction Common Lisp (intégrée) renvoie plus de 2 valeurs? J'en connais beaucoup qui retournent 2, mais je ne peux pas en penser à un qui retourne 3.
(J'ai vu un commentaire sur le renvoi de plus de 2 valeurs et j'ai essayé de penser à un cas où CL l'a fait, mais ne peut pas.)
La solution
Il existe une fonction get-setf-expansion. Il retourne 5 valeurs.
Autres conseils
Oui, de telles fonctions existent. Voici la liste complète des fonctions du package COMMON-LISP qui renvoient exactement trois valeurs, telles que déclarées dans le code source SBCL:
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
De plus, les fonctions suivantes renvoient un nombre constant de valeurs supérieures à trois:
DECODE-UNIVERSAL-TIME required: 9, optional: 0, rest?: NIL
GET-DECODED-TIME required: 9, optional: 0, rest?: NIL
Ces fonctions renvoient un nombre variable de valeurs, donc éventuellement plus de trois:
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.)
Explications sur les colonnes: required
correspond au nombre minimal de valeurs renvoyées pour ces fonctions, optional
un nombre fixe de valeurs renvoyées pouvant, selon SBCL, être renvoyées ou non, rest?
indique qu'un nombre variable de valeurs devrait. (Seuls macroexpand
et macroexpand-1
utilisent réellement & Et facultatif, ne me demandez pas pourquoi.)
Et juste pour le plaisir, voici le code source que j'avais l'habitude de créer avec ces tableaux:
(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))))
decode-universal-time renvoie neuf valeurs.
VALEURS et VALUES-LIST , entre autres.