scheme中的可选参数和点

scheme中的可选参数和点,scheme,racket,optional-parameters,Scheme,Racket,Optional Parameters,所以,我想看看可以接受任意数量参数的函数是如何工作的 我试过这个 (define (plus x . xs) (if (null? xs) x (plus (+ x (car xs)) . (cdr xs)))) (plus 1 2 3 4) (define (plus* x . xs) (if (null? xs) x (let ((h (car xs)) (t (crd xs))) (plus* (+

所以,我想看看可以接受任意数量参数的函数是如何工作的

我试过这个

(define (plus x . xs)
  (if 
   (null? xs) x
   (plus (+ x (car xs)) . (cdr xs))))
(plus 1 2 3 4)
(define (plus* x . xs)
  (if 
   (null? xs) x
   (let ((h (car xs))
         (t (crd xs)))            
     (plus* (+ x h) . t))))
但看起来它实际上并没有将cdr应用于xs,而是在调试器中通过它时传入((2 3 4))。所以我试过这个

(define (plus x . xs)
  (if 
   (null? xs) x
   (plus (+ x (car xs)) . (cdr xs))))
(plus 1 2 3 4)
(define (plus* x . xs)
  (if 
   (null? xs) x
   (let ((h (car xs))
         (t (crd xs)))            
     (plus* (+ x h) . t))))
思考:“哈,我想看到你现在通过cdr”,但我得到了一个错误:“应用程序:错误语法(非法使用“.”)in:(加*(+xh).t)”

发生了什么事

(我可以通过

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

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

因此,加法不是问题,虚线的工作原理是什么。)

您的上一个版本是将数字列表作为输入传递给
plus
——您必须使用
apply
。(好吧,要么这样,要么像使用
foldl
那样避免整个过程)在应用程序中使用点并不是做你认为应该做的事情——它会使程序读起来不同。

它做什么?如果不是那样的话,如何使用点呢?
(x.y)
被解读为cons单元格,在其
car
中有
x
,在其cdr中有
y
,也就是说,它不是一个合适的列表。类似地,
(x.(y))
是一个cons单元格,在其
汽车中有
x
,在其
cdr中有列表
(y)
,因此它与读取
(xy)
相同。因此,当你写
(加上x.(cdr t))
时,就如同你写
(加上x cdr t)
一样,这解释了你得到的令人困惑的结果。顺便说一句,Racket有一个语法系统,可以区分两者,并以不同的方式对待使用这样的
输入的表达式,但这并没有做到,因为它在其他情况下可能会导致更大的混乱。让我们失败吧。我在:(plus*(+xh.t)中得到了“application:bad语法(非法使用“.”)”。同样,如果我使用裸lambda表单,让它也展开。这都在上面,唯一能帮助您的是运行
(read)
,并用点输入代码——然后查看实际读取的内容。