List 为什么可以';我不能在方案中的出租声明中使用汽车吗?

List 为什么可以';我不能在方案中的出租声明中使用汽车吗?,list,scheme,racket,sicp,cons,List,Scheme,Racket,Sicp,Cons,以下方案代码可以正常工作: (define (same-parity x . numbers-input) (define (check-parity a) (= (remainder x 2) (remainder a 2))) (define (iter numbers-left) (cond ((null? numbers-left) nil) ((check-parity (car numbers-left)) (cons (car numbers-l

以下方案代码可以正常工作:

(define (same-parity x . numbers-input)
  (define (check-parity a) (= (remainder x 2) (remainder a 2)))
  (define (iter numbers-left)
    (cond ((null? numbers-left) nil)
          ((check-parity (car numbers-left)) (cons (car numbers-left) (iter (cdr numbers-left))))
          (else (iter (cdr numbers-left))))) 
  (cons x (iter numbers-input)))
它应该输出一个列表,第一个元素是整数x,后续元素是输入的数字中与x具有相同奇偶校验的所有整数

如果有人感兴趣,这是我试图解决书中的练习2.20

现在,我想用变量“first”和“rest”替换(汽车号码左)和(cdr号码左)

现在尝试调用此函数时出现错误:

> (same-parity 1 2 3 4 5)
. . mcar: contract violation
  expected: mpair?
  given: ()
Racket在let声明中突出显示了(左车号)。即使我从来没有在函数体中实际调用“first”或“rest”,只是保持以前的方式,我也会得到同样的错误

然而,在下面的代码中,我试图在一个简单的测试定义中复制上述过程的结构,令人惊讶的是,这正如您所期望的那样有效

(define (test x . testlist)
  (define (test2 test2list)
    (let ((first (car test2list)))
      first))
  (test2 testlist))

> (test 1 2 3 4 5)
2
事实证明,如果我用一个简单的调用替换原始程序中的(cond…),它也可以正常工作,因此(cond…)语句会禁止我使用变量

我知道这是一件非常具体的事情,我不知道这是否真的很重要(除非你想让代码更具可读性),但我真的很想知道它为什么会这样做


如有任何见解,将不胜感激

变量的值在您定义它们时立即进行评估,无论您是否使用它们。因此,当列表变为空时,您将在递归结束时调用
(car'())
。您从未到达试图退出的
cond
部分

(define (test x . testlist)
  (define (test2 test2list)
    (let ((first (car test2list)))
      first))
  (test2 testlist))

> (test 1 2 3 4 5)
2