2010-11-15 38 views
5

Donc, j'essaie de voir comment fonctionnent les fonctions qui peuvent accepter n'importe quel nombre d'arguments?Arguments optionnels et points dans le schéma

J'ai essayé

(define (plus x . xs) 
    (if 
    (null? xs) x 
    (plus (+ x (car xs)) . (cdr xs)))) 
(plus 1 2 3 4) 

Mais est semblait qu'il ne demandait pas réellement cdr à xs, mais en passant ((2 3 4)) quand je suis entré à travers elle dans le débogueur. J'ai donc essayé cette

(define (plus* x . xs) 
    (if 
    (null? xs) x 
    (let ((h (car xs)) 
     (t (crd xs)))    
    (plus* (+ x h) . t)))) 

Pensée: « ha, je voudrais vous voir passer cdr maintenant », mais je reçois une erreur: « l'application: syntaxe incorrecte (. L'utilisation illégale de` ') dans: (plus * (+ xh) t) "

Que se passe-t-il?

(je peux obtenir une version de plus de travail, que ce soit par

(define (add . xs) 
    (foldl + 0 xs)) 

Ou encore

(define (plus x . xs) 
    (if 
    (null? xs) x 
    (apply plus (cons (+ x (car xs)) (cdr xs))))) 

donc, l'addition est pas le problème, comment les choses en pointillés travail est.)

Répondre

6

Votre dernière version est la bonne façon de passer une liste de nombres comme entrées à plus - vous doit utiliser apply pour le faire. (Eh bien, soit, ou éviter le tout comme vous l'avez fait avec foldl.) L'utilisation d'un point dans l'application ne fait pas ce que vous pensez qu'il devrait faire - cela rend le programme lu différemment.

+0

Que fait-il à la place? Comment utilise-t-on le point, sinon comme ça? –

+3

'(x. Y)' est lu comme une contre-cellule avec 'x' dans son' car' et 'y' dans son cdr - c'est-à-dire que ce n'est pas une liste correcte. De même, '(x. (Y))' est une cellule par contre avec 'x' dans son' car', et la liste '(y)' dans son 'cdr' - c'est donc la même chose que lire' (xy) '. Donc, quand vous écrivez '(plus x. (Cdr t))', c'est comme si vous écriviez '(plus x cdr t)', ce qui explique les résultats confus que vous avez obtenus. –

+0

Note BTW que Racket a un système de syntaxe qui permet de distinguer les deux, et de traiter une expression qui a été entrée avec un tel '.' différemment - mais cela n'est pas fait car cela peut conduire à une confusion encore plus grande situations. –