2009-01-30 6 views
3

Est-ce qu'une fonction Common Lisp (intégrée) renvoie plus de 2 valeurs? Je connais beaucoup qui retournent 2, mais je ne peux pas penser à un qui renvoie 3.Est-ce qu'une fonction Common Lisp renvoie 3 valeurs?

(J'ai vu un commentaire ici sur le retour de plus de 2 valeurs, et j'ai essayé de penser à un cas où CL a fait cela, mais peut 't.)

Répondre

4

Il existe une fonction get-setf-expansion. Il renvoie 5 valeurs.

7

Le décodage-temps-universel renvoie neuf valeurs.

+0

D'oh, vous avez raison. Je le savais. Vraiment. – Ken

27

Oui, de telles fonctions existent. Voici la liste complète des fonctions dans le package Common Lisp qui renvoient exactement trois valeurs, comme déclaré 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 

En outre, 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 peut-être plus que 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 des colonnes: required est le nombre minimum de valeurs de retour pour ces fonctions, optional un nombre fixe de valeurs de retour que SBCL pense pourrait ou ne peut pas être retourné, rest? indique qu'un nombre variable de valeurs est attendu. (Seuls les macroexpand et macroexpand-1 réellement utiliser & en option, ne me demandez pas pourquoi.)

Et juste pour le plaisir, voici le code source que je venais avec ces 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)))) 
Questions connexes